인지야공/인공 지능 공부 치트 시트 정리/4번째 글
seaborn 치트시트를 다시 쓴다 — figure 수준과 axes 수준
seaborn 은 함수가 많아 보이지만 실은 두 종류뿐이다. 이 구분을 모르면 “왜 서브플롯 안에 안 들어가지”에서 멈추고, 알고 나면 나머지는 인자 이름 문제다.
확인 환경은 seaborn 0.13.2 다. 손에 있던 DataCamp 치트시트는 꽤 오래된 판이라 그대로 치면 에러가 나는 줄이 여럿 있었고, 그건 뒤쪽에 모았다. ADP 시험장은 0.9.0 이라 반대로 안 되는 것이 또 따로 있다.
figure 수준과 axes 수준
| figure 수준 | axes 수준 | |
|---|---|---|
| 예 | relplot displot catplot lmplot pairplot jointplot | scatterplot lineplot histplot boxplot barplot countplot heatmap regplot |
| 반환 | FacetGrid (그림 전체) | Axes (좌표계 하나) |
ax= 를 줄 수 있나 | 없다 | 있다 |
col= row= 로 쪼갤 수 있나 | 있다 | 없다 |
figure 수준 함수는 자기가 Figure 를 직접 만든다. 그래서 남이 만든 축에 그려 넣을 수 없다.
fig, ax = plt.subplots()
sns.relplot(data=df, x="x", y="y", ax=ax)
# UserWarning: relplot is a figure-level function and does not accept the `ax` parameter.
# 에러가 아니라 경고다 — ax 는 무시되고 그림이 따로 하나 더 생긴다
직접 만든 서브플롯 안에 넣을 것이면 axes 수준을 쓴다. 이 한 문장이 seaborn 사용법의 절반이다.
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
sns.histplot(data=df, x="tip", ax=axes[0]) # axes 수준이라 들어간다
sns.boxplot(data=df, x="day", y="tip", ax=axes[1])
반대로 조건별로 그림을 쪼갤 것이면 figure 수준이다. col=, row= 가 그 일을 한다.
sns.relplot(data=tips, x="total_bill", y="tip", hue="sex", col="time", kind="scatter")
세 갈래로 외운다
figure 수준 함수 셋이 각각 한 갈래를 맡고, kind= 로 안에서 갈린다. axes 수준 함수 이름이
그대로 kind 값이라 따로 외울 것이 없다.
| 갈래 | figure 수준 | kind 로 고르는 것 |
|---|---|---|
| 관계 | relplot | scatter(기본) · line |
| 분포 | displot | hist(기본) · kde · ecdf |
| 범주 | catplot | strip(기본) · swarm · box · violin · bar · count · point |
sns.catplot(data=titanic, x="pclass", y="survived", hue="sex", kind="bar")
sns.displot(data=df, x="tip", kde=True)
sns.lmplot(data=iris, x="sepal_width", y="sepal_length", hue="species") # 회귀선까지
데이터는 긴 형태로 준다
seaborn 의 인자 이름은 전부 열 이름이다. 그래서 pandas 글에서 말한 tidy 형태 — 한 행이 한 관측, 한 열이 한 변수 — 가 그대로 전제가 된다.
sns.boxplot(data=df, x="day", y="tip", hue="smoker")
# ~~~~~~~ ~~~~~~ ~~~~~~ ~~~~~~~~~~ 전부 df 의 열 이름이다
| 인자 | 하는 일 |
|---|---|
x, y | 축에 놓을 변수 |
hue | 색으로 나눈다 (한 그림 안에서) |
col, row | 그림을 쪼갠다 (figure 수준에서만) |
size, style | 점 크기·모양으로 나눈다 |
넓은 형태(변수마다 열이 따로)라면 pd.melt 로 긴 형태로 바꾸고 넣는다.
실기에서 실제로 쓰는 몇 개
# 상관행렬 — 수치가 같이 보여야 쓸모가 있다
corr = df.corr(numeric_only=True)
sns.heatmap(corr, annot=True, fmt=".2f", cmap="coolwarm", vmin=-1, vmax=1)
# 변수 관계를 한눈에 (열이 많으면 느리다. 5~6개로 추린 뒤 쓴다)
sns.pairplot(iris, hue="species")
# 분포 + 개별 점을 겹쳐 본다. axes 수준이라 겹쳐 그릴 수 있다
sns.boxplot(data=df, x="day", y="tip", showfliers=False)
sns.stripplot(data=df, x="day", y="tip", color="black", alpha=0.4)
df.corr() 에 문자열 열이 섞여 있으면 최근 pandas 에서는 에러가 난다. numeric_only=True 를
붙이는 것이 안전하다.
모양 손보기
sns.set_theme(style="whitegrid") # 0.11 부터. 예전 sns.set() 의 새 이름이다
sns.set_style("whitegrid") # 스타일만 바꿀 때
sns.despine(left=True) # 테두리 선 지우기
g = sns.catplot(...) # figure 수준의 반환값은 FacetGrid 다
g.set_axis_labels("x 라벨", "y 라벨")
g.set_xticklabels(rotation=45)
g.figure.suptitle("제목") # 안의 Figure 로 내려가 matplotlib 을 그대로 쓴다
ax = sns.boxplot(...) # axes 수준의 반환값은 Axes 다
ax.set_title("제목") # 이후는 matplotlib 과 똑같다
seaborn 은 matplotlib 위에 얹힌 것이라, 꾸미기는 결국 matplotlib 으로 내려가서 한다. 그쪽은 matplotlib 글에 적어 두었다.
치트시트가 낡은 부분
DataCamp 치트시트의 예제를 0.13.2 에서 그대로 쳐 보고 정리한 것이다.
| 치트시트 | 0.13.2 에서 | 대신 |
|---|---|---|
sns.factorplot(...) | 없다(0.9 에서 catplot 으로 이름이 바뀌었다) | sns.catplot(...) |
sns.distplot(data.y) | 경고 — 0.14 에서 제거 예정 | sns.histplot (axes) / sns.displot (figure) |
sns.jointplot("x", "y", data=df) | TypeError (0.12 부터 키워드 전용) | sns.jointplot(data=df, x="x", y="y") |
sns.countplot(x="deck", data=t, palette="Greens_d") | FutureWarning — hue 없이 palette 만 주는 것은 폐기 | hue="deck", legend=False 를 같이 준다 |
plt.show(g) | 인자는 의미가 없다 | plt.show() |
위치 인자로 x, y 를 넘기던 옛 표기가 전부 막혔다는 것이 가장 큰 변화다. 0.12 부터
data 를 뺀 나머지는 키워드로만 받는다. 옛 코드를 가져올 때 대부분 여기서 걸린다.
그런데 시험장은 0.9.0 이다
방향이 정확히 반대인 함정이 여기서도 나온다.
| 최신(0.13.2) | 시험장(0.9.0) | |
|---|---|---|
histplot · displot · ecdfplot | 있다 | 없다(0.11 에서 추가) |
distplot | 폐기 예정 | 이걸 써야 한다 |
catplot | 표준 | 있다(0.9 에서 도입) |
sns.countplot(df["col"]) | 돌지만 축이 가로로 뒤집힌다 | 세로 막대로 나온다 |
마지막 줄은 직접 확인한 것이다. 0.13.2 는 첫 위치 인자를 data 로 받기 때문에 시리즈 하나를
넣으면 에러 없이 돌면서 x축이 count, y축이 값으로 바뀐다. 에러가 났으면 차라리 나은데
조용히 다른 그림이 나오는 쪽이라 더 나쁘다. 축을 정하고 싶으면 언제나
sns.countplot(data=df, x="col") 처럼 이름을 붙여 준다.
시험장 버전에 대한 나머지는 시험장 환경 글에 적어 두었다.
출처
DataCamp 의 Python For Data Science Cheat Sheet — Seaborn 을 보고 다시 쓴 것이다. 원본은 DataCamp 치트시트 페이지에서 받을 수 있고, 공식 문서는 seaborn.pydata.org 다. 여기 있는 문장과 코드, 확인 결과는 내가 쓰고 내가 돌려 본 것이다.