강의영상

- (1/2) matplotlib + seaborn (1)

- (2/2) matplotlib + seaborn (2)

maplotlib + seaborn

import matplotlib.pyplot as plt 
import numpy as np 
import seaborn as sns
x=[44,48,49,58,62,68,69,70,76,79] # 몸무게 
y=[159,160,162,165,167,162,165,175,165,172] #키 
g='F','F','F','F','F','M','M','M','M','M'
plt.plot(x,y,'o')
[<matplotlib.lines.Line2D at 0x7fad1f1c0bb0>]
sns.scatterplot(x=x,y=y,hue=g)
<AxesSubplot:>

- 두 그림을 나란히 겹쳐 그릴수 있을까?

fig, (ax1,ax2) = plt.subplots(1,2) 
ax1.plot(x,y,'o')
[<matplotlib.lines.Line2D at 0x7fad1f023070>]
sns.scatterplot(x=x,y=y,hue=g,ax=ax2) 
<AxesSubplot:>
fig
fig.set_figwidth(8)
fig
ax1.set_title('matplotlib')
ax2.set_title('seaborn')
Text(0.5, 1.0, 'seaborn')
fig

- 마치 matplotlib에 seaborn을 plugin하듯이 사용할 수 있다.

matplotlib vs seaborn

- 디자인이 예쁜 패키지를 선택하여 하나만 공부하는 것은 그렇게 좋은 전략이 아니다.

sns.set_theme()
plt.plot([1,2,3],[3,4,5],'or')
[<matplotlib.lines.Line2D at 0x7fad1e572d60>]

예제

- 아래와 같은 자료가 있다고 하자.

np.random.seed(43052)
x=np.random.normal(size=1000,loc=2,scale=1.5)

- 이 자료가 정규분포를 따르는지 어떻게 체크할 수 있을까?

plt.hist(x)
(array([ 10.,  24.,  99., 176., 232., 222., 165.,  53.,  16.,   3.]),
 array([-2.44398446, -1.53832428, -0.6326641 ,  0.27299608,  1.17865626,
         2.08431645,  2.98997663,  3.89563681,  4.80129699,  5.70695718,
         6.61261736]),
 <BarContainer object of 10 artists>)

- 종모양이므로 정규분포인듯 하다.

- 밀도추정곡선이 있었으면 좋겠다. (KDE로 추정) $\to$ seaborn을 활용하여 그려보자.

sns.histplot(x,kde=True)
<AxesSubplot:ylabel='Count'>

- 종모양인것 같다.

- 그렇다면 아래는 어떤가?

np.random.seed(43052)
from scipy import stats 
y=stats.t.rvs(10,size=1000)
sns.histplot(y,kde=True)
<AxesSubplot:ylabel='Count'>

- 종모양이다..?

- 비교

fig, (ax1,ax2) = plt.subplots(1,2) 
sns.histplot(x,kde=True,ax=ax1)
sns.histplot(y,kde=True,ax=ax2)
<AxesSubplot:ylabel='Count'>
xx= (x-np.mean(x)) / np.std(x,ddof=1) 
yy= (y-np.mean(y)) / np.std(y,ddof=1) 

fig, (ax1,ax2) = plt.subplots(1,2) 
sns.histplot(xx,kde=True,ax=ax1)
sns.histplot(yy,kde=True,ax=ax2)
<AxesSubplot:ylabel='Count'>
xx= (x-np.mean(x)) / np.std(x,ddof=1) 
yy= (y-np.mean(y)) / np.std(y,ddof=1) 

fig, ((ax1,ax2),(ax3,ax4)) = plt.subplots(2,2) 
ax1.boxplot(xx) 
sns.histplot(xx,kde=True,ax=ax2)
ax3.boxplot(yy)
sns.histplot(yy,kde=True,ax=ax4)
<AxesSubplot:ylabel='Count'>
fig.tight_layout()
fig

- 주의: 아래와 같이 해석하면 잘못된 해석이다.

  • $y$ 히스토그램을 그려보니 모양이 종모양이다. $\to$ $y$는 정규분포이다

- 관찰: boxplot을 그려보니 $y$의 꼬리가 정규분포보다 두꺼워 보인다.

숙제

sns.set_theme(style="whitegrid", palette="pastel")
plt.plot([1,2,3])
[<matplotlib.lines.Line2D at 0x7fad7db14790>]

와 같이 테마를 바꿔서 그림을 그려보고 스샷제출