차트 선택 가이드
민서가 프로젝트 데이터를 앞에 두고 고민했습니다. 배운 차트가 열 가지가 넘는데, 지금 이 데이터에 무엇을 써야 하는지 막막했습니다.
강주원 선배가 말했습니다.
"차트를 외우려고 하지 마. 질문을 따라가다 보면 자연스럽게 도착해."
의사결정 트리
아래 흐름을 따라가면 적절한 차트에 도달할 수 있습니다.
변수가 몇 개인가?│├─ 1개 (단일 변수)│ └─ 무엇을 보고 싶은가?│ ├─ 어디에 몰려 있는지 → histplot, kdeplot│ ├─ 전체의 몇 %가 이하인지 → ecdfplot│ └─ 개별 위치 확인 → rugplot (다른 차트와 조합)│├─ 2개│ ├─ 둘 다 연속형│ │ ├─ 관계/패턴을 보고 싶다 → scatterplot│ │ ├─ 추세선이 필요하다 → regplot, lmplot│ │ └─ 예측 오차를 확인한다 → residplot│ ││ ├─ x는 범주형, y는 연속형│ │ ├─ 평균만 보고 싶다 → barplot│ │ ├─ 빈도를 세고 싶다 → countplot│ │ ├─ 분포 범위를 보고 싶다 → boxplot│ │ ├─ 분포 모양을 보고 싶다 → violinplot│ │ └─ 개별 점을 보고 싶다 → swarmplot, stripplot│ ││ └─ x가 시간/순서인 경우│ └─ 시간에 따른 변화 → lineplot│└─ 3개 이상 (다변수) ├─ 변수 간 전체 상관관계 → heatmap (corr()) ├─ 비슷한 패턴을 묶고 싶다 → clustermap └─ 모든 변수 쌍을 비교 → pairplot (PART 03에서 다룸)
Seaborn 함수 매핑 표
| 목적 | 추천 함수 | 수준 | 비고 |
|---|---|---|---|
| 두 연속 변수의 관계 | scatterplot | Axes | hue로 그룹 구분 가능 |
| 시간/순서에 따른 변화 | lineplot | Axes | 신뢰구간 자동 표시 |
| 관계/변화를 패널로 분할 | relplot | Figure | col, row 파라미터 |
| 그룹별 평균 비교 | barplot | Axes | estimator 변경 가능 |
| 그룹별 빈도 | countplot | Axes | y 지정 불필요 |
| 그룹별 분포 범위 | boxplot | Axes | 이상치 자동 표시 |
| 그룹별 분포 모양 | violinplot | Axes | split=True로 절반 분할 |
| 개별 데이터 점 (겹침 허용) | stripplot | Axes | 데이터 많을 때 적합 |
| 개별 데이터 점 (겹침 없음) | swarmplot | Axes | 수백 개 이하 권장 |
| 단일 변수 분포 (막대) | histplot | Axes | kde=True로 곡선 오버레이 |
| 단일 변수 분포 (곡선) | kdeplot | Axes | 2D도 가능 |
| 누적 분포 | ecdfplot | Axes | 백분위 읽기 용이 |
| 데이터 위치 표시 | rugplot | Axes | 다른 차트와 조합 |
| 회귀선 (단일 Axes) | regplot | Axes | ci, order 조정 |
| 회귀선 (패널) | lmplot | Figure | hue별 별도 회귀선 |
| 잔차 분석 | residplot | Axes | 모델 적합도 확인 |
| 상관행렬 색상 표현 | heatmap | Axes | annot, mask 활용 |
| 군집 기반 히트맵 | clustermap | Figure | 행/열 자동 재배열 |
Figure-level vs Axes-level
Seaborn 함수에는 두 가지 종류가 있습니다. 이 차이를 알면 코드 오류를 줄일 수 있습니다.
| 구분 | Axes-level | Figure-level |
|---|---|---|
| 예시 | scatterplot, barplot, histplot | relplot, catplot, displot, lmplot |
| 반환값 | Axes 객체 | FacetGrid 객체 |
| ax= 파라미터 | 사용 가능 | 사용 불가 |
| col, row 분할 | 불가 | 가능 |
| plt.subplots()와 함께 | 사용 | 사용 하지 않음 |
ax= 파라미터를 써서 여러 차트를 한 Figure에 배치하려면 Axes-level 함수를 씁니다. 데이터를 자동으로 분할해 여러 패널을 만들려면 Figure-level 함수를 씁니다.
민서의 차트 선택 체크리스트
프로젝트 데이터를 앞에 두고 이 순서대로 확인합니다.
1단계: 변수 파악
- 이번에 보려는 변수는 몇 개인가.
- 각 변수는 연속형(숫자)인가, 범주형(그룹)인가, 시간 순서인가.
2단계: 질문 명확화
- 분포를 보고 싶다 → 분포 차트(histplot, kdeplot, ecdfplot)
- 두 변수의 관계를 보고 싶다 → scatterplot, regplot
- 그룹을 비교하고 싶다 → barplot, boxplot, violinplot
- 시간 흐름을 보고 싶다 → lineplot
- 전체 변수의 관계를 보고 싶다 → heatmap, pairplot
3단계: 그룹 분할 필요 여부
- 단순히 색으로 구분 → hue 파라미터
- 여러 패널로 분할 → col, row (Figure-level 함수 필요)
- 두 그룹을 하나의 바이올린에서 비교 → violinplot(split=True)
4단계: 데이터 수 고려
- 수십~수백 개이고 점을 모두 보고 싶다 → swarmplot
- 수백~수천 개이고 겹침을 허용한다 → stripplot(alpha 낮춤)
- 수천 개 이상이고 패턴만 중요하다 → boxplot, violinplot, kdeplot
5단계: 발표/보고 목적 고려
- 발표 슬라이드 → 단순하고 큰 차트. 하나에 하나의 메시지
- 탐색적 분석 → 여러 변수를 한 번에. pairplot, heatmap
- 논문/보고서 → boxplot+swarmplot 조합, 신뢰구간 포함
가장 흔한 실수
민서가 팀원들과 이야기하며 정리한 실수 목록입니다.
첫 번째, 범주형 x에 scatterplot을 쓰는 것. x가 요일처럼 순서 없는 범주라면 boxplot이나 barplot이 맞습니다.
두 번째, 히스토그램으로 그룹 비교를 하는 것. 두 그룹의 분포를 비교할 때 히스토그램을 겹쳐 그리면 읽기 어렵습니다. kdeplot(fill=True)이나 violinplot이 훨씬 명확합니다.
세 번째, Figure-level 함수에 ax= 파라미터를 주는 것. relplot, lmplot, catplot은 ax=를 받지 않습니다. 이미 존재하는 Axes에 그리려면 각 함수의 Axes-level 버전(scatterplot, regplot, barplot 등)을 씁니다.
네 번째, 상관계수 없이 히트맵을 그리는 것. 원시 데이터를 바로 heatmap에 넣으면 스케일이 다른 변수들이 섞여 해석이 어렵습니다. df.corr()으로 상관행렬을 먼저 만들거나, standard_scale로 정규화합니다.