파이썬 Seaborn 라이브러리 다차원 데이터 시각화 로드맵
Seaborn으로 다변량 데이터를 시각화해보자

지난 시간에는 파이썬의 Seaborn 라이브러리를 이용해 변수가 1개인 단변량 데이터(univariate data)를 시각화하는 법을 살펴보았습니다. 이번 시간에는 변수가 2개인 이변량 데이터(bivariate data)와 3개 이상인 다변량 데이터(multivariate data)를 시각화는 법을 알아보겠습니다. Seaborn 사용을 위한 기본 환경 설정 방법과 그래프 스타일링, 1차원 데이터를 시각화하는 방법을 알고 싶은 분들은 파이썬 데이터 시각화 Seaborn 사용법 기초편을 먼저 읽으시기를 추천드립니다.

다변량 데이터를 시각화하는 그래프의 종류는 다음과 같습니다.

  1. 다차원 범주형 데이터 시각화
  • 빈도 막대그래프(병렬): catplot(kind='count')
  • 빈도 막대그래프(다중, 누적): countplot
  • 요약 통계값 막대그래프: barplot
  • 요약 통계값 포인트그래프: pointplot
  • 상자그림: boxplot, boxenplot, violinplot
  1. 다차원 수치형 데이터 시각화
  • 점그래프(dot plot): stripplot, swarmplot
  • 선분그래프(rug plot): rugplot
  • 히스토그램(histogram): histplot
  • 밀도그림(density plot): kdeplot
  • 경험적 누적분포함수(empirical cumulative distribution function): ecdfplot
  1. 다차원 데이터 관계 시각화
  • 선그래프(line plot): lineplot
  • 산점도(scatter plot): scatterplot
  • 결합/주변분포도(joint/marginal distribution plot): jointplot
  • 산점도 행렬(scatter plot matrix): pairplot
  • 상관 행렬(correlation matrix): heatmap, clustermap
  • 회귀 그래프(regression plot): regplot, lmplot, residplot
Seaborn 다차원 데이터 시각화 로드맵
Seaborn 다차원 데이터 시각화 로드맵 

준비

실습을 위해서는 개발 환경(development environments)과 데이터가 필요합니다. 먼저 개발 환경부터 알아보겠습니다.

기본 환경 설정

글에서는 개발 환경으로 주피터 노트북(Jupyter notebook)을 사용했습니다. 여기서는 시각화 실습을 하는데 필요한 최소한의 설정만 적용하겠습니다. 코드별 자세한 설명은 Matplotlib 사용법(예정)을 참조해 주세요. 주피터 노트북의 자세한 환경설정 방법은 주피터 노트북 환경 설정하기를 참조하시면 됩니다. 코드는 다음과 같습니다.

python
# 패키지 임포트
import numpy as np # Numpy(넘파이) 패키지 임포트
import pandas as pd # pandas(판다스) 패키지 임포트
import matplotlib.pyplot as plt # Matplotlib(맷플롯립) 패키지의 pyplot 모듈을 plt로 임포트
from matplotlib import rcParams # 한글 환경 설정을 위한 rcParams 임포트
import seaborn as sns # Seaborn(씨본) 패키지 임포트
import warnings
# 한글 환경 설정
def setting_styles_basic():
rcParams['font.family'] = 'Malgun Gothic' # Windows
# rcParams['font.family'] = 'AppleGothic' # Mac
rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 기호가 깨지는 현상 방지
setting_styles_basic()
# 경고창 무시
warnings.filterwarnings('ignore')

다음으로는 그래프의 스케일(scale)을 조정하겠습니다. 스케일 조정은 sns.set_context 함수를 이용해 설정할 수 있습니다. Seaborn의 다양한 스타일링 방법은 파이썬 데이터 시각화 Seaborn 사용법 기초편의 스타일링 부분을 참조해 주세요. 코드 실행 결과는 그래프 전역에 적용됩니다. 코드는 다음과 같습니다.

python
sns.set_context('paper', # notebook, talk, poster
rc={'font.size':15,
'xtick.labelsize':15,
'ytick.labelsize':15,
'axes.labelsize':15})

실습을 위한 기본적인 환경 설정을 마쳤다면 다음은 데이터를 준비할 차례입니다.

데이터

실습을 위해서 Seaborn의 내장 데이터를 load_dataset() 함수를 이용해 로딩해 오겠습니다. 특정 데이터셋은 Sklearn(사이킷런)에서 불러와 pandas의 DataFrame으로 변경하겠습니다. 사용할 데이터는 다음과 같습니다.

python
df_titanic = sns.load_dataset('titanic') # 타이타닉호 데이터
df_iris = sns.load_dataset('iris') # 붓꽃 데이터
df_penguins = sns.load_dataset('penguins') # 펭귄 데이터
df_tips = sns.load_dataset('tips') # 팁 데이터
df_diamonds = sns.load_dataset('diamonds') # 다이아몬드 데이터
df_planets = sns.load_dataset('planets') # 행성 데이터
df_flights = sns.load_dataset('flights') # 비행 데이터
from sklearn.datasets import load_wine
wine_data = load_wine()
df_wines = pd.DataFrame(data=wine_data.data, # 와인 데이터
columns=wine_data.feature_names)

그럼 지금부터 다변량 데이터를 시각화하는 법을 살펴보겠습니다. 다변량 데이터는 변량이 2개인 이변량 데이터와 변량이 3개 이상인 데이터를 포함합니다. 다변량 데이터를 그래프로 표현할 때는 색상으로 구분하는 hue, 캔버스로 구분하는 col, 점 크기로 구분하는 size 등의 파라미터를 이용해 시각화 차원을 넓혀나갈 수 있습니다. 먼저 다변량 범주형 데이터를 시각화해 보겠습니다.

다차원 데이터 시각화: 범주형

다변량 범주형 자료를 시각화하는 Seaborn의 그래프는 빈도 막대그래프(병렬, 다중, 누적)가 있습니다.

1) 빈도 막대그래프: countplot()

빈도 막대그래프(카운트플롯)은 범주형 데이터의 개수를 표현합니다.

병렬 빈도 막대그래프

병렬 막대그래프는 두 변량에 대한 빈도 막대그래프 2개를 각각의 캔버스(canvas)에 병렬로 나열한 그래프입니다. Seaborn으로 병렬 빈도 막대그래프를 그리려면 catplot() 함수에 kind='count'col 옵션을 추가하면 됩니다. countplot() 함수로는 병렬 막대그래프를 그릴 수 없습니다.

python
sns.catplot(x='class',
col='who', # 캔버스 분리하기
kind='count', # 빈도 막대그래프 그리기
data=df_titanic)
countplot() 함수로 그린 병렬 빈도 막대그래프
countplot() 함수로 그린 병렬 빈도 막대그래프 

다중 빈도 막대그래프

다중 빈도 막대그래프는 countplot() 또는 catplot()hue 파라미터를 설정해서 그릴 수 있습니다. hue 옵션은 변량을 색상으로 구분하는 파라미터입니다. 먼저 수직 다중 빈도 막대그래프부터 그려보겠습니다.

수직 다중 빈도 막대그래프

countplot() 함수 또는 caplot() 함수로 수직 다중 빈도 막대그래프를 그리려면 해당 함수의 x 파라미터에 가로축 범주로 사용할 DataFrame의 열 이름을 입력하고, hue 파라미터에 다른 색상으로 구분할 DataFrame의 열 이름을 입력하면 됩니다. 코드는 다음과 같습니다.

python
sns.countplot(x='class', hue='who', data=df_titanic) # 코드1
# 또는
# 코드2
sns.catplot(x='class', hue='who', kind='count',
palette='pastel', # 색상 팔레트 지정: {'man': 'b', 'woman': 'g', 'child': 'r'}
edgecolor='.6', # 막대 테두리 색상 투명도 지정
data=df_titanic)
countplot() 함수로 그린 수직 다중 막대그래프
countplot() 함수로 그린 수직 다중 막대그래프 

histplot() 함수에 multiple='dodge' 옵션을 주어도 다중 빈도 막대그래프를 그릴 수 있습니다. histplot() 함수는 수치형 자료를 히스토그램으로 만들 때 사용하는 함수이지만, 히스토그램의 막대 사이에 간격을 주고 x축 눈금을 없애면 히스토그램을 일반 막대그래프처럼 만들 수 있습니다. 예시 코드는 다음과 같습니다.

python
ax = sns.histplot(x='sex', hue='survived',
multiple='dodge', # 다중 막대그래프 그리기
shrink=.8, # 막대 사이 간격 조정
data=df_titanic)
ax.tick_params(bottom=False) # x축 눈금 숨기기
histplot() 함수로 그린 수직 다중 막대그래프
histplot() 함수로 그린 수직 다중 막대그래프 

이번에는 수평 다중 막대그래프를 그려보겠습니다.

수평 다중 빈도 막대그래프

수평 다중 막대그래프를 그리고 싶다면 수직 다중 막대그래프를 그릴 때 사용한 함수에 x 파라미터 대신 y 파라미터를 사용하면 됩니다.

python
sns.countplot(y='class', hue='who', data=df_titanic) # 코드1
# 또는
sns.catplot(y='class', hue='who', kind='count',
palette='pastel', edgecolor='.6',
data=df_titanic) # 코드2
countplot() 함수로 그린 가로 그룹형 막대그래프
countplot() 함수로 그린 가로 그룹형 막대그래프 

누적 빈도 막대그래프

Seaborn으로 누적 빈도 막대그래프를 만들려면 histplot() 함수에 multiple='stack' 옵션을 주면 됩니다.

수직 누적 빈도 막대그래프
python
ax = sns.histplot(x='sex', hue='survived',
multiple='stack', # 누적 막대그래프 그리기
shrink=.8, # 막대 사이 간격 조정
data=df_titanic)
ax.tick_params(bottom=False) # x축 눈금 안 보이게 하기
histplot() 함수로 그린 단순 수직 누적 막대그래프
histplot() 함수로 그린 단순 수직 누적 막대그래프 
수평 누적 빈도 막대그래프

수평 누적 빈도 막대그래프를 그리려면 x 파라미터 대신 y 파라미터를 사용하면 됩니다.

python
ax = sns.histplot(y='sex', hue='survived',
multiple='stack', # 누적 막대그래프 그리기
shrink=.8, # 막대 사이 간격 조정
palette='pastel', # 색상 팔레트 지정
data=df_titanic);
ax.tick_params(left=False) # y축 눈금 안 보이게 하기
histplot() 함수로 그린 단순 수평 누적 막대그래프
histplot() 함수로 그린 단순 수평 누적 막대그래프 

2) 요약 통계량 막대그래프: barplot()

요약 통계량 막대그래프는 범주형 자료에 대한 수치형 데이터를 부트스트랩 샘플링(원본 데이터와 동일한 크기의 샘플을 여러 번 복원 추출)하여 얻은 표본들의 평균과 그 평균의 신뢰구간(confidence interval)을 나타낸 막대그래프입니다. 신뢰구간은 막대 위 검정색 오차 막대(error bar)로 표현됩니다. 요약 통계값 막대그래프를 그리려면 barplot() 함수를 사용하면 됩니다. catplot() 함수에 kind='bar' 옵션을 주어도 됩니다.

기본적으로는 복원 샘플링된 표본들의 평균과 95% 신뢰구간이 표현되지만 estimator 파라미터와 ci 파라미터로 각각 요약 통계값과 신뢰구간을 지정할 수 있습니다. 옵션은 다음과 같습니다.

  • estimator: 중앙값 np.median, 합계 np.sum
  • ci: 신뢰구간 지정(기본값: 95), sd로 설정 시 표준편차(standard deviation)로 변경 가능, None으로 설정 시 오차 막대 제거
  • n_boot: 부트스트랩 샘플링 횟수(기본값: 1000)

먼저 수직 요약 막대그래프를 그리는 법부터 알아보겠습니다.

기본

수직 요약 막대그래프

수직 평균 막대그래프를 그리는 코드는 다음과 같습니다.

python
sns.barplot(x='day', y='total_bill', data=df_tips)
# 또는
sns.catplot(x='day', y='total_bill', kind='bar', data=df_tips)
barplot() 함수로 그린 수직 요약 막대그래프
barplot() 함수로 그린 수직 요약 막대그래프 
수평 요약 막대그래프

만일 요약 막대그래프를 수평으로 그리고 싶다면 barplot() 함수에 orient='h' 옵션을 추가하면 됩니다.

python
sns.barplot(x='total_bill', y='day', orient='h', data=df_tips)
barplot() 함수로 그린 수평 요약 막대그래프
barplot() 함수로 그린 수평 요약 막대그래프 

다중 요약 막대그래프

barplot() 함수에 hue 파라미터를 추가하면 색상으로 구분되는 다중 요약 막대그래프를 그릴 수 있습니다.

수직 다중 요약 막대그래프

다음은 변량이 3개인 데이터를 수직 다중 요약 막대그래프로 표현하는 예시 코드입니다.

python
sns.barplot(x='day', y='total_bill',
hue='smoker', data=df_tips)
barplot() 함수로 그린 수직 요약 다중 막대그래프
barplot() 함수로 그린 수직 요약 다중 막대그래프 
수평 다중 요약 막대그래프

수평 다중 요약 막대그래프를 그리고 싶으면 orient=h 파라미터값을 추가하면 됩니다.

python
sns.barplot(x='total_bill', y='day',
hue='smoker', orient='h', data=df_tips)
barplot() 함수로 그린 수평 요약 다중 막대그래프
barplot() 함수로 그린 수평 요약 다중 막대그래프 

누적 요약 막대그래프

누적 요약 막대그래프를 그리고 싶다면 barplot() 함수에 dodge=False을 추가하면 됩니다. Seaborn에서 누적 막대그래프는 평균값을 나타내는 막대의 최댓값 위에 다른 평균값을 나타내는 막대를 쌓아서 만드는 것이 아니라 그래프 자체를 서로 겹쳐서 그린 것입니다.

python
sns.barplot(x='day', y='total_bill',
hue='smoker', dodge=False,
data=df_tips)
barplot() 함수로 그린 누적 요약 막대그래프1
barplot() 함수로 그린 누적 요약 막대그래프1 

누적 요약 막대그래프는 barplot() 함수를 연이어 사용해서 그릴 수도 있습니다.

python
s1 = sns.barplot(x='species', y='sepal_length',
color='coral', ci=None, data=df_iris)
s2 = sns.barplot(x='species', y='petal_length',
color='powderblue', ci=None, data=df_iris)
barplot() 함수로 그린 누적 요약 막대그래프2
barplot() 함수로 그린 누적 요약 막대그래프2 

위 그래프에서 막대의 y축값(색칠된 부분)은 각각 sepal_length의 평균과 petal_length의 평균을 나타냅니다.

3) 포인트 플롯: pointplot()

포인트플롯은 막대그래프와 동일한 정보를 제공합니다. 대신 평균값을 막대 대신 점(point)으로 표현합니다. 포인트플롯은 pointplot() 함수를 사용해서 그립니다. 포인트플롯은 한 화면에 여러 그래프를 비교할 때 유용합니다.

python
sns.pointplot(x='day', y='total_bill', data=df_tips)
# 또는
sns.catplot(x='day', y='total_bill', kind='point', data=df_tips)
pointplot() 함수로 그린 기본 포인트 플롯
pointplot() 함수로 그린 기본 포인트 플롯 

만일 신뢰구간이 아니라 표준편차를 표현하고 싶다면 ci='sd'를 추가하면 됩니다. 선과 포인트를 다른 모양으로 표현할 수도 있습니다. 예시 코드는 다음과 같습니다.

python
sns.pointplot(x='class', y='survived', hue='sex',
palette={'male': 'g', 'female': 'm'},
markers=['^', 'o'], # 마커 지정
linestyles=['-', '--'], # 선 스타일 지정
data=df_titanic)
옵션을 추가한 포인트 플롯
옵션을 추가한 포인트 플롯 

4) 상자그림: boxplot(), boxenplot(), violinplot()

상자그림(박스플롯)은 데이터의 분위를 5가지 요약 수치(five-number summary)로 제공하는 도표입니다.

  • 제3사분위수 (Q3): 전체 데이터 중 상위 25%에 해당하는 값, 박스의 위쪽 경계선으로 표시
  • 제2사분위수 (Q2 또는 중앙값): 전체 데이터의 50%에 해당하는 값(중앙값), 박스 내부의 선으로 표시
  • 제1사분위수 (Q1): 전체 데이터 중 하위 25%에 해당하는 값, 박스의 아래쪽 경계선으로 표시
  • 사분위 범위 (IQR): Q3 - Q1, 박스의 높이로 표현
  • 최댓값 (Maximum): 이상치를 제외하고 데이터셋에서 가장 큰 값, 박스플롯에서 위쪽 수염의 끝점으로 표시
  • 최솟값 (Minimum): 이상치를 제외하고 데이터셋에서 가장 작은 값, 박스플롯에서 아래쪽 수염의 끝점으로 표시
  • 이상치 (Outliers): 일반적으로 Q1 - 1.5IQR 미만이거나 Q3 + 1.5IQR 초과인 값들을 개별 점으로 표시

기본

Seaborn에서 상자그림을 만들려면 boxplot() 함수를 이용하면 됩니다. catplot() 함수에 'kind='box'` 옵션을 추가해도 됩니다.

python
sns.boxplot(data=df_iris)
# 또는
sns.catplot(data=df_iris, kind='box')
boxplot()으로 그린 수직 상자그림
boxplot()으로 그린 수직 상자그림 

만일 상자그림을 수평으로 그리고 싶다면 orient='h' 옵션을 추가하면 됩니다.

python
sns.boxplot(data=df_iris, orient='h')
boxplot()으로 그린 수평 상자그림
boxplot()으로 그린 수평 상자그림 

3차원 박스플롯은 hue 옵션을 추가해서 그릴 수 있습니다. hue 파라미터를 더하면 비슷한 속성의 데이터끼리 분류할 수 있습니다.

python
df_tips['weekend'] = df_tips['day'].isin(['Sat', 'Sun'])
sns.boxplot(x='total_bill', y='day', hue='weekend',
orient='h',
dodge=False,
data=df_tips)
boxplot()으로 그린 수평 상자그림2
boxplot()으로 그린 수평 상자그림2 

박슨 플롯

박슨 플롯은 데이터를 여러 개의 분위로 나눈 박스플롯입니다. 박슨 플롯은 데이터셋을 더 많은 분위수(quantiles)로 나누어 기존의 상자그림보다 이상치(outliers)에 대해 더 많은 정보를 제공합니다. 따라서, 박슨 플롯은 큰 데이터셋을 처리하기에 적합합니다.

박슨 플롯을 만들려면 boxenplot()을 이용하면 됩니다. catplot() 함수에 kind='boxen' 옵션을 추가해도 됩니다.

python
sns.boxenplot(x='color', y='price',
data=df_diamonds.sort_values('color'))
# 또는
sns.catplot(x='color', y='price', kind='boxen',
data=df_diamonds.sort_values('color'))
boxenplot()으로 그린 박슨 플롯
boxenplot()으로 그린 박슨 플롯 

바이올린 플롯

바이올린 플롯은 상자그림과 KDE 방법을 이용해 추정한 확률밀도함수(커널밀도추정 함수)를 합친 그래프입니다. Seaborn으로 바이올린 플롯을 그리고 싶다면 violinplot() 함수를 이용하면 됩니다. catplot() 함수에 kind='violin' 옵션을 추가해도 동일한 결과를 얻을 수 있습니다.

python
sns.violinplot(x='total_bill', y='day', data=df_tips)
# 또는
sns.catplot(x='total_bill', y='day', kind='violin', data=df_tips)
violinplot()으로 그린 바이올린 플롯
violinplot()으로 그린 바이올린 플롯 

이진 데이터를 추가로 표현하고 싶다면 huesplit=True 파라미터를 사용하면 됩니다.

violinplot()으로 그린 바이올린 플롯2
violinplot()으로 그린 바이올린 플롯2 

5) 모자이크 그래프

막대그래프 외에도 변량이 모두 범주형인 다차원 데이터를 시각화할 때는 모자이크 그래프(mosaic plot)를 사용하기도 합니다. 모자이크 그래프는 그룹 내의 데이터 백분율을 보여주는 누적 막대그래프입니다. 모자이크 그래프는 변수가 3개 이상일 때도 사용할 수 있습니다.

모자이크 그래프는 statmodels.graphics.mosaic 패키지의 mosaic() 함수를 이용해서 그립니다. 코드는 다음과 같습니다.

python
from statsmodels.graphics.mosaicplot import mosaic
import matplotlib.pyplot as plt
props = lambda key: {'color': 'teal' if '1' in key else 'lightgray'}
labelizer = lambda k: {('female','1'): '여성\n(생존)', ('female','0'): '여성\n(사망)',
('male','1'): '남성\n(생존)', ('male', '0'): '남성\n(사망)'}[k]
mosaic(df_titanic.sort_values('sex'),
['sex', 'survived'],
properties=props, # 색상 변경
labelizer=labelizer, # 라벨 변경
axes_label=False) # 축 라벨 숨기기
plt.title('타이타닉호 성별 생존자', fontsize=17) # 제목 내용 및 글자 크기 설정
mosaic 함수로 그린 모자이크 플롯
mosaic 함수로 그린 모자이크 플롯 

지금까지 Seaborn으로 다변량 범주형 데이터를 시각화하는 법을 살펴보았습니다. 이번에는 다변량 수치형 데이터를 시각화하는 법을 알아보겠습니다.

다차원 데이터 시각화: 수치형

1) 점그래프: stripplot(), swarmplot()

점그래프는 데이터포인트를 점으로 나타낸 도표입니다. 점그래프를 이용하면 데이터의 실제 위치와 분포를 한눈에 파악할 수 있습니다. Seaborn에서 점그래프를 그리는 기본 함수는 stripplot()입니다.

stripplot

python
sns.stripplot(data=df_tips)
# 또는
sns.catplot(kind='strip', data=df_tips)
stripplot() 함수로 그린 점도표
stripplot() 함수로 그린 점도표 

stripplot() 함수에 jitter 옵션을 추가하면 데이터포인트를 일렬로 그릴 수 있습니다.

  • jitter: 지터(jitter)는 데이터 값에 약간의 노이즈를 추가하는 것, 노이즈를 추가하면 데이터 값이 조금씩 움직여서 같은 값을 가지는 데이터가 그래프에 여러 번 겹쳐서 표시되는 현상을 막아줌
python
sns.stripplot(x='total_bill', y='smoker',
jitter=False,
data=df_tips)
stripplot() 함수로 그린 점도표2
stripplot() 함수로 그린 점도표2 

데이터포인트가 서로 겹치는 것을 방지하려면 dodge=True 옵션을 사용하면 됩니다.

  • dodge=True: hue로 구분된 그룹 사이 간격을 만들어 데이터가 겹치는 것을 방지
python
sns.stripplot(x='tip', y='day',
palette='Spectral', # 색상 팔레트 지정
dodge=True,
data=df_tips)
stripplot() 함수로 그린 점도표3
stripplot() 함수로 그린 점도표3 

dodge=True 옵션처럼 점그래프에서 데이터 포인트들이 서로 겹치지 않고 새의 무리처럼 보이게 그래프를 만드는 방법도 있습니다. 이때 사용하는 함수가 swarmplot()입니다.

swarmplot

swarmplot() 함수를 이용하면 점도표의 데이터포인트를 떼(swarm)처럼 무리를 만들어 데이터포인트가 중첩되는 문제를 해결할 수 있습니다. 떼 플롯을 그리는 기본 코드는 다음과 같습니다.

python
sns.swarmplot(data=df_tips)
# 또는
sns.catplot(kind='swarm', data=df_tips)
swarmplot() 함수로 그린 데이터포인트 분포: 전체 변수
swarmplot() 함수로 그린 데이터포인트 분포: 전체 변수 

xy 파라미터를 사용하면 각 변수에 대한 떼 플롯을 만들 수 있습니다.

python
sns.swarmplot(x='day', y='total_bill', data=df_tips)
# 또는
sns.catplot(x='day', y='total_bill', kind='swarm', data=df_tips)
swarmplot() 함수로 그린 데이터포인트 분포: 특정 변수
swarmplot() 함수로 그린 데이터포인트 분포: 특정 변수 

실제 데이터포인트를 점이 아니라 선분(rug)으로 표현할 수도 있습니다.

2) 선분그래프: rugplot()

실수 데이터의 분포를 선분으로 표현하고 싶다면 rugplot() 함수를 이용하면 됩니다. rugplot()은 데이터포인트를 각 축 위에 보여줍니다.

python
sns.rugplot(x='total_bill', y='tips', data='df_tips')
rugplot() 함수로 그린 선분그래프
rugplot() 함수로 그린 선분그래프 

보통 선분그래프는 다른 그래프와 함께 그립니다. 그래프를 겹쳐 그리려면 그래프 함수를 연이어 사용하면 됩니다.

python
sns.scatterplot(x='total_bill', y='tip', data=df_tips)
sns.rugplot(x='total_bill', y='tip', data=df_tips)
rugplot() 함수와 scatterplot() 함수로 그린 그래프
rugplot() 함수와 scatterplot() 함수로 그린 그래프 

3) 히스토그램: histplot()

Seaborn에서 히스토그램을 만드는 함수는 histplot()입니다. displot() 함수를 이용해도 됩니다. Seaborn에서 histplot() 함수로 이변량 히스토그램(bivariate histogram)을 그릴 때는 변량을 색상으로 구분합니다. 여기서는 histplot() 대신 displot()을 이용해 히스토그램을 만들어 보겠습니다.

기본 히스토그램

python
sns.histplot(x='flipper_length_mm', hue='species', data=df_penguins) # 코드1
# 또는
sns.displot(x='flipper_length_mm', hue='species', data=df_penguins) # 코드1

옵션을 이용하면 다양한 종류의 히스토그램을 그릴 수 있습니다.

  • hue: 그룹별 히스토그램
  • multiple='stack': 누적 히스토그램(포개지 않고 쌓기)
  • multiple='dodge': 다중 히스토그램
python
sns.displot(x='flipper_length_mm', hue='species',
element='step', data=df_penguins) # 코드2
sns.displot(x='flipper_length_mm', hue='species',
multiple='stack', data=df_penguins) # 코드3
sns.displot(x='flipper_length_mm', hue='sex',
multiple='dodge', data=df_penguins) # 코드4
displot() 함수로 그린 다양한 히스토그램1
displot() 함수로 그린 다양한 히스토그램1 
python
sns.displot(x='bill_length_mm', y='species', hue='species',
legend=False, data=df_penguins)
displot() 함수로 그린 히스토그램2
displot() 함수로 그린 히스토그램2 
  • log_scale=True: x축 값 로그 스케일로 변환
  • element='poly': 그래프를 분포다각형(distribution polygon)으로 지정
  • fill=False: 그래프 선 아래 색깔 채우지 않기
python
sns.displot(x='distance', hue='method', log_scale=True,
element='poly', fill=False, data=df_planets)
displot() 함수로 그린 히스토그램3
displot() 함수로 그린 히스토그램3 

한 캔버스 내에 여러 그래프를 그리지 않고 그래프를 서로 다른 캔버스에 나누어서 그리고 싶다면 col 옵션을 사용하면 됩니다. col 옵션은 그래프를 개별 캔버스에 나누어 그려줍니다.

python
sns.displot(x='flipper_length_mm',
col='sex', # 성별에 따라 캔버스 구분
data=df_penguins)
displot 함수로 그린 히스토그램4
displot 함수로 그린 히스토그램4 

만일 두 변량이 모두 수치형이라면 이변량 히스토그램은 히트맵(heatmap) 같은 모양을 띠게 됩니다.

  • binwidth: 직사각형 크기 지정
  • cbar: 색 집중도에 따른 빈도수를 나타내는 컬러바 유무 지정
  • hue: 색으로 구분되는 그룹별 그래프 설정(분포 간 중복되는 부분이 적어야 함)
python
# 코드1: 2차원 - 기본
sns.displot(x='bill_length_mm', y='bill_depth_mm',
data=df_penguins)
# 코드2: 2차원 - 직사각형 넓이 조정
sns.displot(x='bill_length_mm', y='bill_depth_mm', binwidth=(2, .5),
data=df_penguins)
# 코드3: 2차원 - 컬러바 유무 지정
sns.displot(x='bill_length_mm', y='bill_depth_mm', cbar=True,
data=df_penguins)
# 코드4: 3차원 - 그룹별 색으로 분류
sns.displot(x='bill_length_mm', y='bill_depth_mm', hue='species',
data=df_penguins)
displot() 함수로 그린 다변량 히스토그램
displot() 함수로 그린 다변량 히스토그램 
  • bins: 등급 수 지정하기
  • discrete: x축 라벨을 막대 중간에 위치시키기(True)
  • pthresh: 전체 데이터 중에서 해당 비율(0~1)의 셀 투명 처리하기
  • pmax: 포화도 최댓값(0~1) 지정하기
python
# 코드1: 튜플로 x와 y변수 다르게 지정
sns.displot(df_planets, x='year', y='distance',
bins=30, discrete=(True, False), log_scale=(False, True))
# 코드2: 관측치가 없는 부분 색으로 표시(투명하게 표시하지 않기)
sns.displot(df_planets, x='year', y='distance',
bins=30, discrete=(True, False),
log_scale=(False, True),
thresh=None)
# 코드3: 한계점과 포화도 지정
sns.displot(df_planets, x='year', y='distance',
bins=30, discrete=(True, False),
log_scale=(False, True),
pthresh=.05, pmax=.9)
# 코드4: 컬러맵 추가
sns.displot(df_planets, x='year', y='distance',
bins=30, discrete=(True, False),
log_scale=(False, True),
cbar=True, cbar_kws=dict(shrink=.75))
displot() 함수에 다양한 옵션을 적용한 히스토그램6
displot() 함수에 다양한 옵션을 적용한 히스토그램6 

지금까지 여러 가지 옵션을 이용해 다양한 종류의 기본 히스토그램을 그려보았습니다. 만일 그룹별로 관측수가 다른 히스토그램을 비교하고 싶다면, 기본 히스토그램을 정규화(normalization)하면 됩니다.

정규화는 모든 데이터 포인트(data point)가 동일한 정도의 스케일(중요도)로 해석되도록 만드는 과정입니다. 정규화는 모든 데이터 포인트의 중요도를 균등하게 만듭니다. 따라서, 이상치를 지닌 특정 속성이 전체 속성처럼 대표되는 일반화의 오류를 방지할 수 있습니다. 정규화를 거친 히스토그램은 정규 히스토그램(normalized histogram)이 됩니다.

정규화를 위한 스케일링 기준점으로는 전체 관측수와 면적을 이용하는 방법이 있습니다. 먼저 전체 관측수로 정규화한 히스토그램을 만들어보겠습니다.

정규 히스토그램(전체 관측수)

Seaborn에서 전체 관측수로 정규화한 히스토그램을 만들려면 histplot() 함수 또는 displot() 함수에 stat='probability' 또는 stat='percent' 옵션을 추가하면 됩니다. stat 옵션에 probability 인자를 주면 y축이 확률(probability)인 그래프가 그려집니다. 반면, percent 옵션을 사용하면 y축이 백분율(percent)인 그래프가 만들어집니다. 전자의 경우 막대들의 높이를 모두 더하면 1이 되고, 후자의 경우에는 100이 됩니다. 이 옵션을 추가면 각 등급의 빈도수를 전체 관측수로 나눈 정규 히스토그램을 만들 수 있습니다. 예시 코드는 다음과 같습니다.

python
# 코드1: y축이 비율인 정규 히스토그램
sns.histplot(x='flipper_length_mm', hue='species',
stat='probability', data=df_penguins)
# 코드2: y축이 백분율인 정규 히스토그램
sns.histplot(x='flipper_length_mm', hue='species',
stat='percent', data=df_penguins)
전체 관측수로 정규화한 히스토그램
전체 관측수로 정규화한 히스토그램 

여기서 commont_norm 옵션을 False로 지정하면 히스토그램을 전체 관측수가 아니라 개별 그룹의 관측수로 정규화할 수 있습니다. 이때 만들어지는 히스토그램은 서로 독립적입니다.

python
# 코드1: y축이 확률인 개별 히스토그램
sns.histplot(x='flipper_length_mm', hue='species',
stat='probability',
common_norm=False, data=df_penguins)
# 코드1: y축이 백분율인 개별 히스토그램
sns.histplot(x='flipper_length_mm', hue='species',
stat='percent',
common_norm=False, data=df_penguins)
전체관측수로 정규화: 개별 히스토그램
전체관측수로 정규화: 개별 히스토그램 

이번에는 전체 관측수가 아니라 면적으로 정규화한 히스토그램을 만드는 법을 알아보겠습니다.

정규 히스토그램(면적)

Seaborn에서 면적으로 정규화한 정규 히스토그램을 만들려면 stat='density' 옵션을 이용하면 됩니다. 이 옵션은 각 등급의 빈도수를 전체 관측치의 개수와 막대 너비(width)의 곱으로 나눈 정규 히스토그램을 만들어줍니다. 이 히스토그램에서 y축은 밀도(density)가 되고, 각 막대의 넓이를 모두 더한 합은 1이 됩니다. 만일, 독립적인 히스토그램을 그리고 싶다면 common_norms=False 옵션을 추가하면 됩니다. 코드는 다음과 같습니다.

python
# 코드1: y축이 밀도인 정규 히스토그램
sns.displot(df_penguins, x='flipper_length_mm', hue='species',
stat='density')
# 코드2: y축이 밀도인 개별 히스토그램
sns.displot(df_penguins, x='flipper_length_mm', hue='species',
stat='density',
common_norm=False)
면적으로 정규화: 기본 정규 히스토그램 및 개별 히스토그램
면적으로 정규화: 기본 정규 히스토그램 및 개별 히스토그램 

지금까지 Seaborn에서 기본 히스토그램과 2가지 종류의 정규 히스토그램을 만드는 법을 살펴보았습니다. 히스토그램은 직관적입니다. 히스토그램은 데이터의 분포를 빠르고 한눈에 파악하고 싶을 때 사용하면 좋습니다.

하지만 한계도 있습니다. 히스토그램으로 확률밀도함수(Probability Density Function, PDF)를 나타내면 정확하지 않습니다. 히스토그램에서 등급의 수는 아무리 많게 잡아도 유한하기 때문입니다. 확률밀도함수는 매끄러운 곡선인데 히스토그램의 등급은 불연속적이다보니 히스토그램의 모양도 계단과 같이 울퉁불퉁하게 나타납니다.

또한, 히스토그램에서는 등급의 간격과 데이터의 시작 위치에 따라 히스토그램의 모양이 달라집니다. 데이터의 차원(dimension)이 증가할수록 히스토그램으로 데이터의 분포를 분석하거나 모델을 추정하는데 필요한 표본 데이터의 개수도 기하급수적으로 증가한다는 단점도 있습니다.

이러한 히스토그램의 단점을 개선한 방법이 있습니다. 바로 커널밀도추정(Kernel Density Estimation, KDE)입니다. 지금부터는 커널밀도추정이란 무엇인지 그리고 Seaborn 라이브러리를 이용해 KDE 곡선을 그리는 법을 알아보겠습니다.

4) 커널밀도함수 그래프: kdeplot()

커널밀도추정이란 커널 함수(kernel function)를 이용해서 확률변수의 확률밀도함수를 추정하는 비모수적(non-parametric) 통계 방법입니다. 비모수적 방법이란 관측 데이터가 특정 확률분포를 따른다는 전제 없이 실시하는 검정 방법입니다. 커널 함수란 원점을 중심으로 대칭을 이루고, 양의(non-negative) 실수(real-valued)값을 가지며, 적분값이 1인 함수(K)를 뜻합니다. 커널 함수에는 대표적으로 가우시안(Gaussian), 코사인(cosine), Epanechnikov 함수 등이 있습니다.

커널함수 종류
커널함수 종류 

밀도그림(density plot)은 커널 스무딩(kernel smoothing)을 이용해 추정한 히스토그램의 확률밀도함수입니다. KDE에서는 데이터를 커널 함수로 대치하여 히스토그램에서 나타났던 등급의 불연속성 문제를 해결합니다. KDE로 추정한 확률밀도함수는 부드러운 곡선입니다.

단, KDE 방법을 사용할 때는 조건이 있습니다. KDE 방법은 극단값이 없는 연속 자료에 사용합니다. 확률밀도함수는 부드러운 곡선인데 이상치가 있으면 해당 값에서 확률밀도함수가 뾰족한 모양을 띠게 되기 때문입니다. 이상치가 있는 연속 자료에는 KDE 보다는 히스토그램을 사용하는 것이 적합합니다.

Seaborn에서 KDE 방법을 통해 확률밀도함수를 그리려면 kdeplot()을 이용하면 됩니다. displot() 함수에 kind='kde' 옵션을 주어도 됩니다. 이번에는 displot() 함수에 kind='kde' 옵션을 추가해서 그려보겠습니다.

  • multiple='stack': 그래프 쌓아서 그리기
  • multiple='fill': 각 값에서 겹친 분포(stacked distribution) 정규화해서 그리기(단변량일 때만 유효, 모든 값에서 y축의 밀도가 1)
  • fill=True: 그래프 불투명하게 그리기
  • cumulative=True: 누적분포함수 그리기
python
# 코드1: 기본 그래프
sns.displot(df_penguins, x='flipper_length_mm', kind='kde', hue='species')
# 코드2: 그래프 겹쳐서 그리기
sns.displot(df_penguins, x='flipper_length_mm', kind='kde', hue='species',
multiple='stack')
# 코드3: 모든 값에서 겹친 분포 정규화하기
sns.displot(df_penguins, x='flipper_length_mm', kind='kde', hue='species',
multiple='fill')
# 코드4: 그래프 불투명하게 그리기
sns.displot(df_penguins, x='flipper_length_mm', kind='kde', hue='species',
fill=True) # sns.kdeplot에서는 shade=True도 사용 가능
# 코드5: 누적분포함수(Cumulative Distribution Function, CDF) 그리기
sns.displot(df_penguins, x='flipper_length_mm', kind='kde', hue='species',
cumulative=True, common_norm=False, common_grid=True)
# 코드6
sns.displot(df_penguins, x='flipper_length_mm', kind='kde',
hue='species',
fill=True, common_norm=False, palette='crest',
alpha=.5, linewidth=0)
kdeplot() 함수로 그린 다양한 밀도그림
kdeplot() 함수로 그린 다양한 밀도그림 

이변량 KDE 그래프는 등고선(contours)으로 표현됩니다. 각 등고선은 밀도가 같은 지점(iso-proportions)을 이은 것입니다.

  • thresh: 가장 낮은 레벨의 등고선 크기 조정
  • levels: 등고선 개수 또는 모양
python
# 코드1: 2차원 - 기본 그래프
sns.displot(df_penguins, x='bill_length_mm', y='bill_depth_mm', kind='kde')
# 코드2: 2차원 - 등고선 크기 및 개수 조정
sns.displot(df_penguins, x='bill_length_mm', y='bill_depth_mm', kind='kde',
thresh=.2, levels=4)
# 코드3: 2차원 - 개별 등고선 크기 지정
sns.displot(df_penguins, x='bill_length_mm', y='bill_depth_mm', kind='kde',
levels=[.01, .05, .1, .7])
# 코드4: 3차원 - 그룹별 그래프 색으로 구분
sns.displot(df_penguins, x='bill_length_mm', y='bill_depth_mm', kind='kde',
hue='species') # fill=True 추가하면 등고선 안이 색으로 채워짐
다양한 다변량 KDE 등고선 그래프
다양한 다변량 KDE 등고선 그래프 

5) 경험적 누적분포함수: ecdfplot()

경험적 누적분포함수를 그리려면 ecdfplot() 함수를 사용하면 됩니다. displot() 함수에 `kind='ecdf' 옵션을 추가해도 됩니다.

  • hue_order: # 색 순서 지정
  • complementary=True: 상보 누적분포함수(complementary cumulative distribution function, CCDF) 그리기
python
# 코드1
sns.displot(df_penguins, x='flipper_length_mm', kind='ecdf')
# 코드2
sns.displot(df_penguins, x='flipper_length_mm', kind='ecdf',
hue='species')
# 코드3
sns.displot(
data=df_planets, x='distance', hue='method',
hue_order=['Radial Velocity', 'Transit'],
log_scale=True, element='step', fill=False,
cumulative=True, stat='density', common_norm=False)
# 코드4: 상보 누적분포함수 그리기
sns.ecdfplot(data=df_penguins, x='bill_length_mm',
hue='species', complementary=True)
ecdfplot()으로 그린 다양한 경험적 누적분포함수
ecdfplot()으로 그린 다양한 경험적 누적분포함수 

다차원 데이터: 관계

1) 선그래프: lineplot()

선그래프는 시간 경과에 따른 연속형 변수의 변동을 보여주는 그래프입니다. Seaborn으로 선그래프를 그리려면 lineplot()을 이용하면 됩니다. relplot() 함수에 kind='line' 옵션을 주어도 됩니다. 다음은 flights 데이터에서 연별(x축) 평균 탑승객 수(y축)를 표현한 그래프입니다. 음영으로 표시된 부분은 95% 신뢰구간입니다.

python
sns.lineplot(x='year', y='passengers',
data=df_flights)
lineplot()으로 그린 선그래프1
lineplot()으로 그린 선그래프1 

연별(x축) 총 탑승객수(y축)를 표현하면 아래와 같습니다.

python
sns.lineplot(x='year', y='passengers',
data=df_flights.groupby('year').sum())
# 또는
sns.relplot(x='year', y='passengers', kind='line',
data=df_flights.groupby('year').sum())
lineplot()으로 그린 선그래프2
lineplot()으로 그린 선그래프2 

월별 데이터를 표현하고 싶다면 huestyle 옵션을 이용해 데이터를 색상과 스타일로 구분해주면 됩니다.

python
sns.lineplot(x='year', y='passengers',
hue='month', style='month', data=df_flights)
lineplot()으로 그린 선그래프3
lineplot()으로 그린 선그래프3 

pandaspivot() 함수를 이용해 만든 표를 이용해도 위 그래프와 동일한 결과를 얻을 수 있습니다. pivot() 함수는 indexcolumns 파라미터에 전달한 속성을 각각 테이블의 행과 열로 지정해서 values 파라미터에 전달한 수치를 표현합니다.

python
flights_pivot = df_flights.pivot(index='month', columns='year', values='passengers') # 각 연도의 월별 탑승객 수
flights_pivot
# sns.lineplot(data=flights_pivot)
pandas의 pivot()함수로 만든 연별, 월별 탑승객 표
pandas의 pivot()함수로 만든 연별, 월별 탑승객 표 

2) 산점도: scatterplot()

산점도는 두 데이터의 관계를 점으로 표현하는 방법입니다. Seaborn으로 산점도를 그리려면 scatterplot() 함수를 사용하면 됩니다. relplot() 함수에 kind='scatter' 옵션을 추가해도 됩니다.

python
sns.scatterplot(x='bill_length_mm', y='bill_depth_mm', data=df_penguins)
# 또는
sns.relplot(df_penguins['bill_length_mm'], df_penguins['bill_depth_mm'], kind='scatter')
Seaborn으로 그린 2차원 산점도: 기본
Seaborn으로 그린 2차원 산점도: 기본 

이번에는 3차원 데이터를 산점도로 시각화해 보겠습니다. 이전에도 언급했듯 다차원 데이터를 시각화할 때는 hue, col, size 등 데이터를 구분 지어 줄 수 있는 파라미터로 시각화하면 됩니다.

  • style: 마커 모양 자동 지정
  • markers: 마커 모양 수동 지정
  • size: 마커 크기 지정
  • sizes: 마커 크기의 범위 지정
  • legend='full': 모든 데이터포인트 보이게 하기
  • hue_norm: 색상 범위 지정
python
sns.relplot(x='bill_length_mm', y='bill_depth_mm',
hue='island',
size='island',
col='sex',
palette=['gray', 'steelblue', 'g'], sizes=(75, 200),
alpha=.5,
kind='scatter',
data=df_penguins)
Seaborn으로 그린 3차원 산점도
Seaborn으로 그린 3차원 산점도 

3) 결합/주변분포도: jointplot()

결합분포(joint distribution)와 주변분포(marginal distribution)를 그리려면 jointplot() 함수를 이용하면 됩니다. jointplot()은 축 수준(axes-level) 함수입니다.

python
# 코드1: 2차원 - 산점도 + 히스토그램
sns.jointplot(x='bill_length_mm', y='bill_depth_mm', data=df_penguins)
# 코드2: 3차원 - 산점도 + KDE 밀도곡선
sns.jointplot(x='bill_length_mm', y='bill_depth_mm', hue='species',
data=df_penguins)
jointplot() 함수로 그린 기본 결합/주변분포도
jointplot() 함수로 그린 기본 결합/주변분포도 

jointplot() 함수에 kind='kde' 옵션을 추가하면 두 개의 분포는 KDE 그래프를 그립니다. 예제는 다음과 같습니다.

python
# 코드3 - 2차원
sns.jointplot(x='bill_length_mm', y='bill_depth_mm',
kind='hist', # 이변량 히스토그램(사각형) 그리기
space=0, # x축, y축 공간 0으로 만들기
size=5, ratio=4, # 크기, 비율 조정하기
data=df_penguins)
# 코드4 - 2차원
sns.jointplot(x='bill_length_mm', y='bill_depth_mm',
kind='hex', # 이변량 히스토그램(육각형) 그리기
space=0, # x축, y축 공간 0으로 만들기
size=5, ratio=4, # 크기, 비율 조정하기
data=df_penguins)
# 코드5 - 2차원
sns.jointplot(x='bill_length_mm', y='bill_depth_mm',
kind='reg', # 선형회귀선, KDE 밀도곡선 추가
space=0, # x축, y축 공간 0으로 만들기
size=5, ratio=4, # 크기, 비율 조정하기
data=df_penguins)
# 코드6 - 3차원
sns.jointplot(x='bill_length_mm', y='bill_depth_mm',
kind='kde', # KDE 밀도등고선, KDE 밀도곡선 그리기
hue='species',
space=0, # x축, y축 공간 0으로 만들기
size=5, ratio=4, # 크기, 비율 조정하기
data=df_penguins)
jointplot() 함수에 kind 옵션을 더해 그린 다양한 그래프
jointplot() 함수에 kind 옵션을 더해 그린 다양한 그래프 

이밖에도 아래 코드를 참고해서 어떤 그래프가 나오는지 확인해 보세요.

python
# 코드1
sns.jointplot(x='bill_length_mm', y='bill_depth_mm',
marker='+', s=100, marginal_kws=dict(bins=25, fill=False),
height=5, ratio=2, marginal_ticks=True, data=df_penguins)
# 코드2
g = sns.jointplot(x='bill_length_mm', y='bill_depth_mm')
g.plot_joint(sns.kdeplot, color='r', zorder=0, levels=6)
g.plot_marginals(sns.rugplot, color='r', height=-.15, clip_on=False, data=df_penguins)
jointplot() 함수와 여러 그래프 겹쳐 그리기
jointplot() 함수와 여러 그래프 겹쳐 그리기 

더 다양한 종류의 결합분포 및 주변분포를 그리고 싶을 경우에는 그래프 수준(figure-level) 인터페이스인 JointGrid를 이용하면 됩니다. 다음은 JointGrid를 이용해 히스토그램과 박스분포를 그리는 예시 코드입니다.

python
# 코드1
g = sns.JointGrid(data=df_penguins, x='bill_length_mm', y='bill_depth_mm')
g.plot_joint(sns.scatterplot, s=100, alpha=.5, edgecolor='.2', linewidth=.5)
g.plot_marginals(sns.histplot, kde=True)
# 코드2
g = sns.JointGrid(data=df_penguins, x='bill_length_mm', y='bill_depth_mm')
g.plot(sns.regplot, sns.boxplot)
g.refline(x=45, y=16)
JointGrid 클래스로 그린 그래프
JointGrid 클래스로 그린 그래프 

4) 산점도 행렬: pairplot()

산점도 행렬(scatter plot matrix)은 여러 변수들의 모든 가능한 이원 조합을 행렬 형태로 표현한 그래프입니다. 산점도 행렬을 그리고 싶다면 pairplot() 함수를 이용하면 됩니다. 이 함수는 데이터셋의 모든 숫자형 변수 쌍에 대해 산점도를 그립니다. 대각선에는 각 변수의 분포를 보여주는 히스토그램이나 KDE 플롯을 그립니다.

python
# 코드1
sns.pairplot(df_penguins)
pairplot() 함수로 그린 기본 2차원 산점도 행렬
pairplot() 함수로 그린 기본 2차원 산점도 행렬 

corner=True 옵션을 추가하면 산점도 행렬의 절반만 그릴 수도 있습니다.

python
sns.pairplot(df_penguins, corner=True)
절반 2차원 산점도 행렬
절반 2차원 산점도 행렬 

원하는 특정 변수를 지정해서 산점도 행렬을 그릴 수도 있습니다.

python
sns.pairplot(df_penguins,
x_vars=['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm'],
y_vars=['bill_length_mm', 'bill_depth_mm'])
특정 2차원 산점도 행렬
특정 2차원 산점도 행렬 
python
sns.pairplot(df_penguins, kind='hist',
height=2)
2차원 히스토그램 산점도 행렬
2차원 히스토그램 산점도 행렬 
python
sns.pairplot(df_penguins, kind='kde') # KDE 곡선 그리기
2차원 kde 산점도 행렬
2차원 kde 산점도 행렬 
python
sns.pairplot(df_penguins,
plot_kws=dict(marker='+', linewidth=1), # 비대각선 방향에 있는 그래프 옵션
diag_kws=dict(fill=False)) # 대각선 방향에 있는 그래프 옵션
커스텀 2차원 산점도 행렬1
커스텀 2차원 산점도 행렬1 
python
g = sns.pairplot(df_penguins, diag_kind='kde') # 대각선 그래프는 KDE 함수
g.map_lower(sns.kdeplot, levels=4, color='.2') # KDE 곡선 수준과 색 지정하기
커스텀 2차원 산점도 행렬2
커스텀 2차원 산점도 행렬2 

3차원 이상의 산점도 행렬을 그리려면 hue 옵션을 추가하면 됩니다.

python
sns.pairplot(df_penguins, hue='species',
markers=['o', 's', 'D'], # 마커 지정
diag_kind='hist') # 대각선 방향에 들어갈 그래프: 히스토그램
3차원 산점도 행렬1
3차원 산점도 행렬1 
python
sns.pairplot(df_penguins,
hue='species',
size=2, aspect=1.8,
plot_kws=dict(linewidth=0.5, alpha=0.3),
diag_kind='kde',
diag_kws=dict(shade=True))
3차원 산점도 행렬2
3차원 산점도 행렬2 

더 세밀한 산점도 행렬을 그리고 싶다면 그래프 수준 인터페이스인 PairGrid 클래스를 이용하면 됩니다. PairGrid 클래스로는 그리고 싶은 그래프를 직접 지정할 수 있습니다. 다음은 kdeplot()histplot() 함수를 이용해 이변량 히스토그램과 KDE 그래프를 그리는 예제입니다.

python
g = sns.PairGrid(df_penguins)
g.map_upper(sns.histplot)
g.map_lower(sns.kdeplot, fill=True)
g.map_diag(sns.histplot, kde=True)
PairGrid 클래스로 그린 산점도 행렬
PairGrid 클래스로 그린 산점도 행렬 

5) 상관행렬: heatmap(), clustermap()

heatmap

히트맵(heatmap)은 데이터를 색상의 강도로 표현하는 2차원 그래픽 표현 방식입니다. 히트맵은 변량 간 관계를 한눈에 파악할 수 있어 좋습니다. 히트맵으로는 다양한 관계를 표현할 수 있는데 여기서는 상관행렬을 표현해보겠습니다.

python
df_wines = df_wines.sample(frac=1, random_state=7).reset_index(drop=True) # 샘플 무작위로 만들기
corr = df_wines.corr() # 상관행렬 표 만들기
sns.heatmap(round(corr,1),
annot=True, # 상관계수 표시
fmt='.1f', # 상관계수 소수점 자리
cmap='coolwarm', # 컬러맵 색상 팔레트
vmax=1.0, # 상관계수 최댓값
vmin=-1.0, # 상관계수 최솟값
linecolor='white', # 셀 테두리 색상
linewidths=.05) # 셀 간격
sns.set(rc={'figure.figsize':(10,7)}) # 그래프 크기
heatmap() 함수로 그린 기본 상관행렬 히트맵
heatmap() 함수로 그린 기본 상관행렬 히트맵 

clustermap

클러스터맵(clustermap)은 데이터 시각화 기법 중 하나로, 히트맵과 계층적 클러스터링을 결합한 형태입니다. Seaborn으로 클러스터맵을 그리려면 clustermap() 함수를 이용하면 됩니다. clustermap() 함수에는 heatmap() 함수와 달리 standard_sacle 파라미터가 있어 클러스터맵의 범위를 0~1로 정규화할 수 있습니다.

python
corr = df_wines.corr() # 상관행렬 표 만들기
sns.clustermap(corr,
cmap='coolwarm', # 컬러맵 색상 팔레트
standard_scale=1)
clustermap() 함수로 그린 상관행렬 클러스터맵
clustermap() 함수로 그린 상관행렬 클러스터맵 

6) 회귀 그래프

Seaborn으로 회귀 그래프를 그리고 싶다면 regplot() 또는 lmplot()을 이용하면 됩니다. 먼저 regplot() 사용법부터 살펴보겠습니다.

regplot

regplot() 함수는 산점도와 선형 회귀선(linear regression line)을 함께 그려주는 함수입니다. 선형 회귀선 주변 음영은 신뢰구간(95%)을 나타냅니다.

python
sns.regplot(x='bill_length_mm', y='bill_depth_mm',
data=df_penguins)
regplot()으로 그린 기본 회귀 그래프
regplot()으로 그린 기본 회귀 그래프 

여기에 lowess=True 옵션을 추가하면 회귀선을 선형이 아니라 중요한 데이터에 가중치를 높이는 국소 회귀(local regression) 기법으로 그립니다. lowesslocally weighted robust scatterplot smoothing의 약자입니다.

python
sns.regplot(x='bill_length_mm', y='bill_depth_mm',
lowess=True,
data=df_penguins)
국소 회귀 기법으로 그린 회귀 그래프
국소 회귀 기법으로 그린 회귀 그래프 
  • scatter_kws: 점 색상(facecolor, fc), 점 테두리 색상(edgecolor, ec), 크기(size, s), 투명도 지정
  • color: 선 색상 지정
  • line_kws: 선 굵기(linewidth, lw), 선 스타일(line style, ls), 투명도 지정
  • ci: 신뢰구간 지정(기본값: 95)
python
sns.regplot(x='bill_length_mm', y='bill_depth_mm',
scatter_kws={'fc':'gray', 'ec':'gray', 's':50, 'alpha':0.3},
color='r',
line_kws={'lw':1.5, 'ls':'--','alpha':0.5},
ci=90,
data=df_penguins)
다양한 옵션을 적용한 회귀 그래프
다양한 옵션을 적용한 회귀 그래프 

lmplot

lmplot() 역시 regplot()과 마찬가지로 회귀 그래프를 만들 수 있습니다. 단, lmplot()은 그래프 수준(figure-level) 함수로 FacetGrid를 만듭니다. lmplot()은 그래프 수준 함수이기 때문에 regplot()에서와 달리 hue 또는 col옵션을 사용할 수 있습니다.

python
# 코드1
sns.lmplot(x='bill_length_mm', y='bill_depth_mm',
hue='species',
data=df_penguins)
# 코드2
sns.lmplot(x='bill_length_mm', y='bill_depth_mm',
col='species',
data=df_penguins)
lmplot()으로 그린 회귀 그래프1
lmplot()으로 그린 회귀 그래프1 

전체 데이터포인트를 배경으로 만들고 싶다면 다음 코드를 이용하면 됩니다.

  • truncate=False: 회귀선 x축 끝까지 표현하지 않기
  • facet_kws=dict(sharex=False, sharey=False): x축, y축 공유하지 않기
  • line_kws: 회귀선 스타일 지정하기
  • scatter_kws: 산점도 점 스타일 지정하기
python
g = sns.lmplot(x='bill_length_mm', y='bill_depth_mm',
col='species', row='sex',
height=4,
truncate=False,
line_kws={'color':'steelblue','linestyle':'--' },
data=df_penguins)
axes = g.axes # FacetGrid에서 AxesSubplots을 추출
for ax in axes.ravel(): # AxesSubplots을 순회하여 전체 데이터를 배경으로 표현
sns.regplot(x='bill_length_mm', y='bill_depth_mm',
fit_reg=False, # 전체 회귀선 숨기기
scatter_kws={'fc':'gray', 'ec':'none', 's':30, 'alpha':0.3},
ax=ax,
data=df_penguins)
lmplot()으로 그린 회귀 그래프2
lmplot()으로 그린 회귀 그래프2 

residplot

resideplot()은 실제 데이터포인트와 회귀선과의 잔차(residuals)를 표현하는 함수입니다.

python
sns.residplot(x='bill_length_mm', y='bill_depth_mm',
lowess=True,
data=df_penguins)
resideplot()으로 그린 잔차 그래프
resideplot()으로 그린 잔차 그래프 

지금까지 Seaborn으로 다차원 데이터를 시각화하는 법을 살펴보았습니다. 모두 수고 많으셨습니다.

참고 문헌

0 Comments

©2025 Snug Archive. All rights reserved.

Email: snugarchive@gmail.com