코딩하는 해맑은 거북이

[데이터시각화] Scatter Plot 본문

Data Analysis & Viz

[데이터시각화] Scatter Plot

#CJE 2023. 3. 22.
본 게시물의 내용은 '부스트캠프 AI Tech - Data Visualization(안수빈)' 강의를 듣고 작성하였다.
해당 글은 아래의 7가지를 다룬다.
🍀 Scatter Plot
🍀 Overplotting
🍀 점의 요소와 인지
🍀 상관관계와 인과관계
🍀 추세선
🍀 ETC
🚩 Iris Species

 

🍀 Scatter Plot

- Scatter plot은 점을 사용하여 두 feature간의 관계를 알기 위해 사용하는 그래프
- 산점도 등의 이름으로 사용됨
- 직교 좌표계에서 x축/y축에 feature 값을 매핑해서 사용
- .scatter()를 사용

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111, aspect=1)

np.random.seed(970725)

x = np.random.rand(20)
y = np.random.rand(20)

ax.scatter(x, y)
ax.set_xlim(0, 1.05)
ax.set_ylim(0, 1.05)

plt.show()

 

- variation 종류 (2차원 데이터에서 N차원 데이터로 확장 가능)

  •  색 (color)
  • 모양 (marker)
  • 크기 (size)
fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111, aspect=1)

np.random.seed(970725)

x = np.random.rand(20)
y = np.random.rand(20)
s = np.arange(20) * 20

ax.scatter(x, y, 
           s= s,  # size
           c='lightblue', # color
           marker='o',
           linewidth=1,
           edgecolor='black') # 테두리 색

plt.show()

 

- 목적1은 상관 관계 확인하기 위함 (양의 상관관계 / 음의 상관관계 / 없음)

- 목적2는 군집, 값 사이의 차이, 이상치를 확인하기 위함

 

 

 

🍀 Overplotting

- 점이 많아질수록 점의 분포를 파악하기가 상당히 힘들다!

- 점의 분포를 파악하는 방법

  • 투명도 조정 : 군집된 곳은 색이 진해지고, 아닌 곳은 연하게 표시됨
  • 지터링 (jittering) : 점의 위치를 약간씩 변경
  • 2차원 히스토그램 : 히트맵을 사용하여 깔끔한 시각화
  • Contour plot : 분포를 등고선을 사용하여 표현

 


🍀 점의 요소와 인지

- 색

  • 연속은 gradient, 이산은 개별 색상으로 한다. 구별하기 쉽다.

- 마커

  • 거의 구별하기 힘들다 + 크기가 고르지 않음

- 크기

  • 흔히 버블 차트(bubble chart)라고 부름
  • 구별하기는 쉽지만 오용하기 쉬움 (원의 크기 비교)
  • 관계보다는 각 점간 비율에 초점을 둔다면 좋음

 


🍀 상관관계와 인과관계

- 인과 관계(causal relation)과 상관 관계(correlation)은 다름!
  → 분석 과정에서 꼭 고민해볼 것
- 인과 관계는 항상 사전 정보와 함께 가정으로 제시할 것.
- 상관관계는 추후 heatmap에서 다시 다룰 예정

 


🍀 추세선

- 추세선을 사용하면 scatter의 패턴을 유추할 수 있음

단, 추세선이 2개 이상이 되면 가독성이 떨어지므로 주의.


🍀 ETC

- Grid는 지양하고 사용한다면 최소한으로 사용한다. 색은 무채색으로 할 것.
- 범주형이 포함된 관계에서는 heatmap 또는 bubble chart를 추천

 

🚩 Iris Species

iris = pd.read_csv('./Iris.csv')
iris.head()

iris.describe(include='all')

* 꽃받침의 길이과 너비 간의 관계를 살펴보자!

fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111)

ax.scatter(x=iris['SepalLengthCm'], y=iris['SepalWidthCm'])

plt.show()

fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111)

slc_mean = iris['SepalLengthCm'].mean()
swc_mean = iris['SepalWidthCm'].mean()

ax.scatter(x=iris['SepalLengthCm'], 
           y=iris['SepalWidthCm'],
           c=['royalblue' if xx <= slc_mean else 'gray' for xx in iris['SepalLengthCm']]
          )   # 꽃받침 길이의 평균보다 작은건 gray로 표현, 큰건 blue

plt.show()

fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111)

slc_mean = iris['SepalLengthCm'].mean()
swc_mean = iris['SepalWidthCm'].mean()

ax.scatter(x=iris['SepalLengthCm'], 
           y=iris['SepalWidthCm'],
           c=['royalblue' if yy <= swc_mean else 'gray' for yy in iris['SepalWidthCm']]
          )   # 꽃받침 너비의 평균보다 작은건 gray로 표현, 큰건 blue

plt.show()

 

 

* 붓꽃의 종류에 따라 시각화해보자!

fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111)

for species in iris['Species'].unique():
    iris_sub = iris[iris['Species']==species]
    ax.scatter(x=iris_sub['SepalLengthCm'], 
               y=iris_sub['SepalWidthCm'], 
               label=species)

ax.legend()    
plt.show()

fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111)

for species in iris['Species'].unique():
    iris_sub = iris[iris['Species']==species]
    ax.scatter(x=iris_sub['PetalLengthCm'], 
               y=iris_sub['PetalWidthCm'], 
               label=species)

ax.legend()    
plt.show()

 

* 시각적인 주의를 위해 선을 사용할 수 있음 : axvline(), axhline()

fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111)

for species in iris['Species'].unique():
    iris_sub = iris[iris['Species']==species]
    ax.scatter(x=iris_sub['PetalLengthCm'], 
               y=iris_sub['PetalWidthCm'], 
               label=species)

ax.axvline(2.5, color='gray', linestyle=':')    # 선 긋기
ax.axhline(0.8, color='gray', linestyle=':')    
ax.legend()    
plt.show()

* 4가지 비교 대상에 대해 모두 출력하기 (중복은 visible을 False로 설정함)

fig, axes = plt.subplots(4, 4, figsize=(14, 14))

feat = ['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm']

for i, f1 in enumerate(feat):
    for j, f2 in enumerate(feat):
        if i <= j : 
            axes[i][j].set_visible(False)
            continue
        for species in iris['Species'].unique():
            iris_sub = iris[iris['Species']==species]
            axes[i][j].scatter(x=iris_sub[f2], 
                               y=iris_sub[f1], 
                               label=species, 
                               alpha=0.7)
        if i == 3: axes[i][j].set_xlabel(f2)
        if j == 0: axes[i][j].set_ylabel(f1)

plt.tight_layout()        
plt.show()

 

 

'Data Analysis & Viz' 카테고리의 다른 글

[데이터시각화] Color  (0) 2023.03.22
[데이터시각화] Text  (0) 2023.03.22
[데이터시각화] Line Plot  (0) 2023.03.22
[데이터시각화] Bar Plot  (0) 2023.03.22
[데이터시각화] Matplotlib  (0) 2023.03.21
Comments