iBetter Books
수정

박스플롯과 바이올린 (boxplot, violinplot)

barplot이 평균 하나를 요약해준다면, boxplot은 더 많은 것을 보여줍니다. 상자 안에 데이터의 절반이 담겨 있고, 수염은 데이터가 얼마나 퍼져 있는지 보여주며, 점들은 극단적으로 멀리 있는 값들입니다.

민서가 물었습니다.

"선배, 이 점들이 다 뭐예요?"

"이상치(outlier)야. 상자에서 한참 떨어진 값들인데, 데이터 입력 오류일 수도 있고 진짜 예외적인 상황일 수도 있어. 무시하면 안 돼."

이 차트가 보여주는 것

boxplot

boxplot의 각 요소가 의미하는 것을 정리합니다.

  • 상자의 아래쪽 선: 1사분위수 (Q1). 전체 데이터의 25%가 이 값보다 작습니다.
  • 상자 안의 선: 중앙값 (Q2). 데이터의 정확히 절반이 이 값보다 작습니다.
  • 상자의 위쪽 선: 3사분위수 (Q3). 전체 데이터의 75%가 이 값보다 작습니다.
  • 상자의 높이 (IQR): Q3 - Q1. 데이터의 가운데 50%가 이 범위 안에 있습니다.
  • 수염(whisker): IQR의 1.5배 범위 안에 있는 최솟값/최댓값
  • 점: 수염 밖에 있는 이상치

"상자는 데이터의 가운데 50%를 담고 있다." 이 한 문장이 핵심입니다.

import seaborn as snsimport matplotlib.pyplot as plttips = sns.load_dataset("tips")sns.boxplot(data=tips, x="day", y="total_bill", hue="smoker")plt.title("요일별 계산 금액 분포 (흡연 여부 구분)")plt.ylabel("계산 금액 (달러)")plt.show()

실행 결과

violinplot: 분포의 모양을 보여준다

boxplot이 사분위수만 보여준다면, violinplot은 데이터가 어디에 얼마나 몰려 있는지 모양으로 보여줍니다. 바이올린이 두꺼운 구간에 데이터가 많이 몰려 있습니다.

violinplot은 KDE(커널 밀도 추정)를 세로로 세워서 양쪽에 대칭으로 붙인 형태입니다.

import seaborn as snsimport matplotlib.pyplot as plttips = sns.load_dataset("tips")sns.violinplot(data=tips, x="day", y="total_bill", hue="sex", split=True)plt.title("요일별 계산 금액 분포 (성별 비교)")plt.ylabel("계산 금액 (달러)")plt.show()

실행 결과

split=True는 hue가 두 범주일 때, 바이올린을 절반씩 나누어 양쪽에 붙여 비교를 직관적으로 만듭니다.

inner 옵션 비교

violinplot 안쪽에 무엇을 표시할지 inner 파라미터로 정합니다.

import seaborn as snsimport matplotlib.pyplot as plttips = sns.load_dataset("tips")fig, axes = plt.subplots(1, 3, figsize=(15, 5))# 사분위수 선sns.violinplot(data=tips, x="day", y="total_bill", inner="quart", ax=axes[0])axes[0].set_title("inner='quart' (사분위수)")# 개별 데이터 막대sns.violinplot(data=tips, x="day", y="total_bill", inner="stick", ax=axes[1])axes[1].set_title("inner='stick' (개별 데이터)")# 박스플롯 내장sns.violinplot(data=tips, x="day", y="total_bill", inner="box", ax=axes[2])axes[2].set_title("inner='box' (박스플롯)")plt.suptitle("inner 옵션 비교", y=1.02)plt.tight_layout()plt.show()

실행 결과

boxplot과 violinplot 함께 쓰기

두 차트의 장점을 결합할 수 있습니다. violinplot으로 전체 분포 형태를 보여주고, 그 위에 boxplot으로 사분위수를 겹쳐 그립니다.

import seaborn as snsimport matplotlib.pyplot as plttips = sns.load_dataset("tips")fig, ax = plt.subplots(figsize=(8, 5))sns.violinplot(    data=tips, x="day", y="total_bill",    color="lightblue", inner=None, ax=ax)sns.boxplot(    data=tips, x="day", y="total_bill",    width=0.15, color="white",    showfliers=False, ax=ax)plt.title("violinplot + boxplot 조합")plt.ylabel("계산 금액 (달러)")plt.show()

실행 결과

inner=None으로 바이올린 내부 표시를 없애고, 그 위에 좁은 boxplot을 올립니다.

언제 어떤 것을 쓸까

차트 보여주는 것 적합한 상황
boxplot 사분위수, 이상치 여러 그룹 간 범위 비교, 이상치 탐지
violinplot 분포의 전체 모양 분포가 정규분포인지, 어디에 몰려 있는지 확인
조합 모양 + 사분위수 발표 자료나 논문 수준의 정밀한 비교