앞선 2개의 포스팅을 통해, 데이터의 종류(수치형 데이터, 범주형 데이터)와 변수의 개수(1개 / 2개 이상)에 따라 어떤 그래프를 그려야 하는지, 각 그래프를 통해 어떤 관계를 파악할 수 있는지 알아보았다.
그런데 EDA를 하다보면 앞에서 그린 그래프처럼 한 번에 1개의 plot만 그리는 경우는 많지 않다.
비교를 위해 1개의 plot에 여러 가지 그래프를 한꺼번에 그리는 경우가 대부분이다.
다른 분들의 EDA 결과물을 참고할 때, 밑의 그림처럼 하나의 plot에 4개의 그래프가 나와 있는 경우를 많이 봤을 것이다.
이번 포스팅에서는 위의 그림처럼 하나의 plot에 여러 가지 그래프를 넣는 방법에 대해 알아본다.
이렇게 그릴 수 있는 방법은 plt.add_subplot(), plt.subplots(), facet_grid 등 여러 가지가 있지만, 나의 경험에 의하면 쓰던 것만 자주 쓰게 되는지라 가장 많이 사용하는 plt.subplots() 라는 유용한 plot 함수를 사용해 그려보자!
여기서도 앞에서 사용한 tips 데이터셋을 활용한다.
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
tips = sns.load_dataset('tips')
✔Table of Contents
4. 한 번에 여러 plot 동시에 그리기: plt.subplots()
4-1. plt.subplots() 사용하는 방법
이 함수를 사용하는 방법은 순서가 있다. 간단한 4가지 순서이므로 이를 꼭 기억해두자.
# Step 1. fig(도화지), axs(축)을 설정한다.
(figsize는 생략 가능)
fig, (ax1, ax2) = plt.subplots(행 개수, 열 개수, figsize = (전체 plot의 가로 길이, 세로 길이))
# Step 2. 각 axs 에 맞는 그림을 그린다.
(주의! 축 ax를 반드시 설정해야 한다. 단, sns가 아닌 plt 기반으로 그린 그림은 ax를 쓰지 않는다.)
ax1 = sns.plot(ax = ax1)
ax2 = sns.plot(ax = ax2)
# Step 3. 각 axs별 그림을 꾸민다. (선택사항)
## 제목
ax1.set_title('제목명')
## x축 이름
ax1.set_xlabel('x축 이름')
## y축 이름
ax1.set_ylabel('y축 이름')
## x축 눈금 설정
ax1.set_xticks(눈금 설정)
## y축 눈금 설정
ax1.set_yticks(눈금 설정)
## 축에 쓰여진 문자 회전하기: axis 값이 'x'(x축), 'y'(y축), 'both'(x,y축 둘 다)
ax1.tick_params(axis = 'x', label_rotation = 각도)
# Step 4. 마무리 (선택사항)
fig.tight_layout()
plt.rc('font', size = 폰트 사이즈) # 그래프의 글자 크기를 변경
plt.show()
4-2. 1개 그래프 그리기
사실 1개 그래프를 그리는 것이라면 굳이 plt.subplots()를 사용해서 그려줄 필요가 없다.
굳이 fig와 axs를 설정하지 않고 그냥 그래프 코드를 써주면 1개 그래프가 나오기 때문이다.
그래도 공부하는 겸, 1개 그래프를 plt.subplots()를 활용해서 그려보자.
# 1개 그래프 subplots 이용해서 그려보기
#step 1
fig, axs = plt.subplots(1, 1, figsize = (5,5))
#step 2
axs = sns.distplot(tips['total_bill'], kde = True, hist = False)
plt.show()
간단히 tips 데이터셋의 total_bill의 distplot을 그려주었다.
1개 그래프이기 때문에 Step 1에서 plt.subplots(1,1)을 입력하였다.
또한 Step 2에서 ax = axs로 써줘야 하지만, 1개 그래프이기 때문에 생략해도 상관없다.
4-3. 2개 그래프 그리기
지금부터 본격적으로 여러가지 그래프를 한번에 그려보자.
먼저 2개 그래프를 그린다. 그림을 어떻게 배치할지부터 먼저 생각해야 하는데, 나는 가로로 2개 그림이 나오게 만들고 싶다.
그럼 행 개수는 1, 열 개수는 2로 설정하면 된다.
2개의 그림은 이전 포스팅에서 활용했던 그래프 2개를 아무거나 가져왔다.
# 1x2 그래프 그리기
#step 1
fig, (ax1, ax2) = plt.subplots(1, 2, figsize = (10,5))
#step 2
ax1 = sns.distplot(tips['total_bill'], kde = True, hist = False, ax = ax1)
ax2 = sns.violinplot(x= 'time', y = 'total_bill', hue = 'sex', data = tips, split = True, ax = ax2)
plt.show()
이렇게 결과가 잘 나왔다!
만일 2개 그래프인데, 세로로 2개 그림이 나오게 하고 싶으면 행 개수를 2, 열 개수를 1로 하면 되겠지?
이번에는 2개 그래프를 그리되, 축을 설정하지 않아도 되는 경우를 알아보자.
바로 seaborn이 아니라, plt 기반으로 그려진 그림은 축을 설정하면 에러가 나기 때문에 이를 설정하지 않는다.
이전에 plt 기반으로 그렸던 그림 중 pie chart가 있던 것이 기억나는가? 이것을 포함해 그래프를 그려보자.
# plt 기반 그림은 ax 축 설정 NO
#step 1
fig, (ax1, ax2) = plt.subplots(1, 2, figsize = (10,5))
#step 2
ax1 = sns.violinplot(x= 'time', y = 'total_bill', hue = 'sex', data = tips, split = True, ax = ax1)
ax2 = plt.pie(x = list(new['sex']),
labels = list(new['index']),
autopct = '%.1f%%') #<- 이 경우는 ax를 쓰지 않음
plt.show()
Step 2에서 pie chart 그림은 두번째 축 ax2에 그려졌다.
첫번째 그림과는 다르게, ax2에 대해선 'ax = ax2' 라는 코드를 넣지 않아야 한다.
4-4. 3개 이상의 그림 그리기: flatten() 활용하기
앞에서 2개의 그림은 Step 1에서 축을 설정할때 다음의 코드를 썼다.
fig, (ax1, ax2) = plt.subplots(1, 2, figsize = (10,5))
하지만 그림의 수가 많아지면 많아질수록 저 코드에 ax1, ax2, ax3, .... , ax100 이렇게 쓰면 에러가 난다.
그래서 나의 경우엔 안전하게 axs를 flatten을 활용해 정의해준다.
예를 들어 4개의 그림을 그린다고 할 때 나는 이렇게 코드를 만들었다.
# step 1
fig, axs = plt.subplots(2, 2, figsize = (10,10))
ax1, ax2, ax3, ax4 = axs.flatten() #<- flatten 활용
# step 2
ax1 = sns.violinplot(x= 'time', y = 'total_bill', hue = 'sex', data = tips, split = True, ax = ax1)
ax2 = sns.regplot(x= 'total_bill', y = 'tip', data = tips, ax = ax2)
ax3 = sns.countplot(x = 'day', data = tips, ax = ax3)
ax4 = plt.pie(x = list(new['sex']),
labels = list(new['index']),
autopct = '%.1f%%') #<- 이 경우는 ax를 쓰지 않음
plt.show()
Step 1의 코드 두번째줄을 보면 flatten()을 활용해 axs를 ax1, ax2, ax3, ax4로 정의하였다.
4-5. 꾸미기 옵션 사용하기(Step 3~4)
지금까지는 꾸미기 옵션을 사용하지 않고, Step 1~2번만 진행했다.
지금부터는 꾸미기를 해보자.
꾸미기를 할 때는 각 plot별로 설정해줄 수 있는데, 이 때 축의 번호(ax1, ax2 같은)에 맞게 설정해주어야 한다.
꾸미는 것에는 대표적으로 plot에 제목을 달아줄 수 있고,
또는 x축이나 y축에 이름을 달아주거나, x축과 y축에 눈금을 설정해줄 수 있다.
먼저 4개의 plot에 하나씩 제목을 달아주었다.
# step 1
fig, axs = plt.subplots(2, 2, figsize = (10,10))
ax1, ax2, ax3, ax4 = axs.flatten() #<- flatten 활용
# step 2
ax1 = sns.violinplot(x= 'time', y = 'total_bill', hue = 'sex', data = tips, split = True, ax = ax1)
ax2 = sns.regplot(x= 'total_bill', y = 'tip', data = tips, ax = ax2)
ax3 = sns.countplot(x = 'day', data = tips, ax = ax3)
ax4 = sns.distplot(tips['total_bill'], kde = True, hist = False, ax = ax4)
# step 3
ax1.set_title('Violinplot of time & total bill(div. by sex)')
ax2.set_title('Scatterplot of total bill & tip')
ax3.set_title('Countplot of day')
ax4.set_title('Kdeplot of total bill')
plt.show()
이렇게 4개의 plot에 제목이 만들어진 것을 볼 수 있다.
이번엔 fig.tight_layout 옵션을 활용해보자. 이것을 사용하면 그래프 사이 간격을 변화하여 보기좋게 만들어준다.
앞에서 만든 코드에 fig.tight_layout()만 추가하였다.
# step 1
fig, axs = plt.subplots(2, 2, figsize = (10,10))
ax1, ax2, ax3, ax4 = axs.flatten() #<- flatten 활용
# step 2
ax1 = sns.violinplot(x= 'time', y = 'total_bill', hue = 'sex', data = tips, split = True, ax = ax1)
ax2 = sns.regplot(x= 'total_bill', y = 'tip', data = tips, ax = ax2)
ax3 = sns.countplot(x = 'day', data = tips, ax = ax3)
ax4 = sns.distplot(tips['total_bill'], kde = True, hist = False, ax = ax4)
# step 3
ax1.set_title('Violinplot of time & total bill(div. by sex)')
ax2.set_title('Scatterplot of total bill & tip')
ax3.set_title('Countplot of day')
ax4.set_title('Kdeplot of total bill')
# step 4
fig.tight_layout()
plt.show()
참고로, 이렇게 제목을 쓰는 것은 Step 2에서 sns.plot() 을 만들어줄 때부터 할 수 있다.
다음의 코드처럼 sns.plot() 뒤에 바로 .set_title()을 설정해주면 된다.
# step 1
fig, axs = plt.subplots(2, 2, figsize = (10,10))
ax1, ax2, ax3, ax4 = axs.flatten() #<- flatten 활용
# step 2~3
ax1 = sns.violinplot(x= 'time', y = 'total_bill', hue = 'sex', data = tips, split = True, ax = ax1).set_title('Violinplot of time & total bill(div. by sex)')
ax2 = sns.regplot(x= 'total_bill', y = 'tip', data = tips, ax = ax2).set_title('Scatterplot of total bill & tip')
ax3 = sns.countplot(x = 'day', data = tips, ax = ax3).set_title('Countplot of day')
ax4 = sns.distplot(tips['total_bill'], kde = True, hist = False, ax = ax4).set_title('Kdeplot of total bill')
fig.tight_layout()
plt.show()
이번에는 y축의 이름을 추가하고, y축의 눈금 설정을 변경해보려고 한다.
4번째 plot의 y축 이름 'prob.' 을 추가하고,
3번째 plot과 4번째 plot의 y축 눈금 범위를 변경해보자.
여기에는 axs.set_ylabel()과 axs.set_yticks()를 사용한다.
# step 1
fig, axs = plt.subplots(2, 2, figsize = (10,10))
ax1, ax2, ax3, ax4 = axs.flatten() #<- flatten 활용
# step 2
ax1 = sns.violinplot(x= 'time', y = 'total_bill', hue = 'sex', data = tips, split = True, ax = ax1)
ax2 = sns.regplot(x= 'total_bill', y = 'tip', data = tips, ax = ax2)
ax3 = sns.countplot(x = 'day', data = tips, ax = ax3)
ax4 = sns.distplot(tips['total_bill'], kde = True, hist = False, ax = ax4)
# step 3
ax1.set_title('Violinplot of time & total bill(div. by sex)')
ax2.set_title('Scatterplot of total bill & tip')
ax3.set_title('Countplot of day')
ax4.set_title('Kdeplot of total bill')
## y축 이름 설정 추가
ax4.set_ylabel('prob.')
## y축 눈금 범위 변경
ax3.set_yticks(np.arange(10, 100, 10))
ax4.set_yticks(np.arange(0,0.1,0.01))
fig.tight_layout()
plt.show()
3번째와 4번째 plot이 이전과 달라진 것이 눈에 띈다.
마지막으로, plot의 전체 제목을 설정해보자.
이는 fig.suptitle() 옵션을 사용하면 된다.
# step 1
fig, axs = plt.subplots(2, 2, figsize = (15,10))
ax1, ax2, ax3, ax4 = axs.flatten() #<- flatten 활용
# step 2
ax1 = sns.violinplot(x= 'time', y = 'total_bill', hue = 'sex', data = tips, split = True, ax = ax1)
ax2 = sns.regplot(x= 'total_bill', y = 'tip', data = tips, ax = ax2)
ax3 = sns.countplot(x = 'day', data = tips, ax = ax3)
ax4 = sns.distplot(tips['total_bill'], kde = True, hist = False, ax = ax4)
# step 3
ax1.set_title('Violinplot of time & total bill(div. by sex)')
ax2.set_title('Scatterplot of total bill & tip')
ax3.set_title('Countplot of day')
ax4.set_title('Kdeplot of total bill')
## y축 이름 설정 추가
ax4.set_ylabel('prob.')
## y축 눈금 범위 변경
ax3.set_yticks(np.arange(10, 100, 10))
ax4.set_yticks(np.arange(0,0.1,0.01))
# 전체 제목 설정
fig.suptitle('Everly made')
fig.tight_layout()
plt.show()
이렇게 해서 글의 첫머리에서 봤던 plot을 만들어보았다!
참고로 포스팅에서 사용한 코드는 깃허브 링크에서 '1. [EDA guide] 주요 데이터 시각화' 파일을 공유해두었으며, 이렇게 파이썬 EDA를 위한 꼭 알아두어야 할 시각화 내용을 정리하였다.
도움이 되셨다면 글 밑에 있는 하트(❤) 눌러주세요! 감사합니다:)
'Skillset > Python, Git' 카테고리의 다른 글
python 열의 문자열을 분리해 N개 열로 만드는 방법(str, split, get) (2) | 2022.06.17 |
---|---|
[pandas] pd.melt, pd.pivot_table을 활용해 데이터프레임 가공하기 (2) | 2022.06.17 |
[시각화] 파이썬 EDA에 꼭 필요한 시각화 그래프 (2) 범주형 데이터 (0) | 2022.06.16 |
[시각화] 파이썬 EDA에 꼭 필요한 시각화 그래프 (1) 수치형 데이터 (0) | 2022.06.15 |
python dlib 설치하기 - anaconda dlib install error (0) | 2022.04.23 |