-
chapter-4 그래프 그리기판다스 2021. 9. 17. 03:33
앤스콤이 지적한 함정과 데이터 시각화의 필요성¶
앤스콤 4분할 그래프를 구성하는 데이터 집합은 4개의 그룹으로 구성되어 있으며 모든 데이터 그룹은 x,y열을 가지고 있습니다. 그런데 이 4개의 데이터 그룹은 각각 평균, 분산과 같은 수칫값이나 상관관계, 회귀선이 같다는 특징이 있습니다. 그래서 이런 결과만 보고 '데이터 그룹 I, II, III, IV의 데이터는 모두 같을 것이다.' 라고 착각할 수 있습니다. 바로 이것이 앤스콤이 지적한 '함정'입니다. 하지만 각 데이터 그룹을 시각화하면 데이터 그룹이 서로 다른 데이터 패턴을 가지고 있다는 점을 금방 알 수 있습니다. 이런 점에서 데이터 시각화는 데이터 분석 분양에서 아주 중요한 요소라고 할 수 있습니다. 그러면 데이터 시각화란 무엇인지 직접 실습하며 알아보겠습니다.
In [2]:import seaborn as sns anscombe=sns.load_dataset("anscombe") print(anscombe) print(type(anscombe))
dataset x y 0 I 10.0 8.04 1 I 8.0 6.95 2 I 13.0 7.58 3 I 9.0 8.81 4 I 11.0 8.33 5 I 14.0 9.96 6 I 6.0 7.24 7 I 4.0 4.26 8 I 12.0 10.84 9 I 7.0 4.82 10 I 5.0 5.68 11 II 10.0 9.14 12 II 8.0 8.14 13 II 13.0 8.74 14 II 9.0 8.77 15 II 11.0 9.26 16 II 14.0 8.10 17 II 6.0 6.13 18 II 4.0 3.10 19 II 12.0 9.13 20 II 7.0 7.26 21 II 5.0 4.74 22 III 10.0 7.46 23 III 8.0 6.77 24 III 13.0 12.74 25 III 9.0 7.11 26 III 11.0 7.81 27 III 14.0 8.84 28 III 6.0 6.08 29 III 4.0 5.39 30 III 12.0 8.15 31 III 7.0 6.42 32 III 5.0 5.73 33 IV 8.0 6.58 34 IV 8.0 5.76 35 IV 8.0 7.71 36 IV 8.0 8.84 37 IV 8.0 8.47 38 IV 8.0 7.04 39 IV 8.0 5.25 40 IV 19.0 12.50 41 IV 8.0 5.56 42 IV 8.0 7.91 43 IV 8.0 6.89 <class 'pandas.core.frame.DataFrame'>
2. matplotlib 라이브러리로 그래프 그리기¶
앤스콤 데이터 집합을 잘 불러왔나요? 데이터 집합이 준비되었으면 이제 그래프로 시각화를 하면 됩니다. 이 책에서는 그래프를 그리기 위해 matplotlib 라이브러리를 사용합니다. 먼저 그래프를 그리기 위해 matplotlib 라이브러리를 불러오겠습니다.
In [100]:%matplotlib notebook import matplotlib.pyplot as plt
3.¶
다음은 anscombe 데이터프레임의 dataset 열에서 데이터 값이 I인 것만 추출한 것입니다. 즉, 첫 번째 데이터 그룹을 추출한 것입니다.
In [101]:dataset_1=anscombe[anscombe['dataset']== 'I']
4.¶
선 그래프는 plot 메서드로 그릴 수 있습니다. plot 메서드에 x,y축 데이터를 전달하면 선 그래프가 나타납니다. 앞에서 준비한 dataset_1의 x,y열을 전달하세요.
In [102]:plt.plot(dataset_1['x'],dataset_1['y'])
Out[102]:[<matplotlib.lines.Line2D at 0x7fa8ac64f250>]
5.¶
plot 메서드는 기본적으로 선으로 그래프를 그립니다. 만약 점으로 그래프를 그리려면 o를 세 번째 인자로 전달하면 됩니다.
In [103]:plt.plot(dataset_1['x'], dataset_1['y'], 'o')
Out[103]:[<matplotlib.lines.Line2D at 0x7fa8ac6687f0>]
앤스콤 데이터 집합 모두 사용해 그래프 만들기¶
앤스콤 데이터 집합은 4개의 데이터 그룹으로 구성되어 있으며 각 데이터 그룹의 차이를 파악하려면 그래프로 시각화해야 한다고 했습니다. 이번에는 모든 데이터 그룹에 대하여 그래프를 그려보겠습니다.
matplotlib 라이브러리로 그래프 그리기¶
이번에 소개할 내용은 'matplotlib 라이브러리로 그래프를 그리는 방법'입니다. 아래에 정리한 과정을 잘 읽어보면 블록을 조립하는 과정과 비슷하다는 것을 알 수 있을 것입니다.
-
- 전체 그래프가 위치할 기본 틀을 만듭니다.
-
- 그래프를 그려 넣을 그래프 격자를 만듭니다.
-
- 그런 다음 격자에 그래프를 하나씩 추가합니다. 격자에 그래프가 추가되는 순서는 왼쪽에서 오른쪽 방향입니다.
-
- 만약 격자의 첫 번째 행이 꽉 차면 두 번째 행에 그래프를 그려 넣습니다.
즉, 이후 실습에서 앤스콤 데이터 집합으로 그리게 될 그래프의 격자 크기는 4이고 세 번째 그래프의 경우 2행 1열 위치에 그려집니다. 잘 이해가 되었나요? 그러면 바로 그래프를 그려 보겠습니다.
In [104]:dataset_2 =anscombe[anscombe['dataset']=='II'] dataset_3 =anscombe[anscombe['dataset']=='III'] dataset_4 =anscombe[anscombe['dataset']=='IV']
2.¶
먼저 그래프 격자가 위치할 기본 틀을 만듭니다.
In [105]:fig= plt.figure()
3.¶
그런 다음 add_subplot 메서드로 그래프 격자를 그립니다. 기본 틀에 격자를 추가한다는 기분으로 add_subplot 메서드를 사용하면 됩니다. add_subplot의 첫 번째 인자에는 그래프 기본 틀의 행 크기를, 두 번째 인자에는 그래프 기본 틀의 열 크기를 지정합니다.
In [106]:fig= plt.figure() axes1=fig.add_subplot(2,2,1) axes2=fig.add_subplot(2,2,2) axes3=fig.add_subplot(2,2,3) axes4=fig.add_subplot(2,2,4)
4.¶
이제 plot 메서드에 데이터를 전달하여 그래프를 그리면 됩니다. 이번에는 점으로 그래프를 표현했습니다. 그래프를 확인하려면 fig를 반드시 입력해야 합니다.
In [107]:axes1.plot(dataset_1['x'], dataset_1['y'], 'o') axes2.plot(dataset_2['x'], dataset_2['y'], 'o') axes3.plot(dataset_3['x'], dataset_3['y'], 'o') axes4.plot(dataset_4['x'], dataset_4['y'], 'o') fig
5.¶
각각의 그래프를 쉽게 구분할 수 있도록 그래프 격자에 제목을 추가해 볼까요? set_title 메서드로 그래프 이름을 전달하면 그래프 격자에 제목이 추가됩니다.
In [108]:axes1.set_title("dataset_1") axes2.set_title("dataset_2") axes3.set_title("dataset_3") axes4.set_title("dataset_4") fig
6.¶
기본 틀에서도 제목을 추가해 볼까요? 기본 틀에 제목을 추가하려면 supitle 메서드를 사용하면 됩니다.
In [109]:fig.suptitle("Anscombe Data") fig
7.¶
그런데 과정 5,6의 그래프를 보면 각 그래프의 이름과 숫자가 겹쳐 보입니다. 이런 경우에는 tight_layout 메서드를 호출하여 각 그래프의 레이아웃을 조절할 수 있습니다.
In [110]:fig.tight_layout() fig
자 어떤가요? 평균, 분산, 상관관계, 회귀선의 통계 수치가 같아도 그래프의 형태는 다를수 있습니다. 앤스콤 4분할 그래프는 데이터 분석 시 수치에만 의존하면 잘못된 판단을 할수 있다는 것을 알려주는 좋은 예시입니다.
04-2 matplotlib 라이브러리 자유자래로 사용하기¶
04-1에서 앤스콤 4분할 그래프를 그릴 때 제목을 추가하기 위해 set_title 메서드를 사용 했던 것을 기억하나요? 이 밖에도 matplotlib 라이브러리에는 그래프를 그리기 위한 다양한 메서드가 준비되어 있습니다. 지금부터 atplotlib 라이브러리에는 어떤 메서드가 있는지 실습을 통해 하나씩 알아보겠습니다. 더불어 고급 그래프 라이브러리인 seaborn 라이브러리도 함께 알아보겠습니다.
기초 그래프 그리기¶
seaborn 라이브러리에는 tips라는 데이터 집합이 있습니다. tips 데이터 집합은 어떤 식당에서 팁을 지불한 손님의 정보를 모아둔 것입니다. 이번 실습에서는 tips 데이터 집합을 사용해 다양한 그래프를 그려보겠습니다. 그래프를 이해하는 데 필요한 개념은 그래프를 그리기 전에 설명하겠습니다.
In [23]:tips =sns.load_dataset("tips") print(tips.head()) print(type(tips))
total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4 <class 'pandas.core.frame.DataFrame'>
2.¶
히스토그램은 데이터프레임의 열 데이터 분포와 빈도를 살펴보는 용도로 자주 사용하는 그래프입니다. 이때 데이터프레임의 total_bill,tip 등의 열을 변수라고 부르기도 합니다. 그리고 변수를 하나만 사용해서 그린 그래프를 '일변량 그래프'라고 부릅니다.
3.¶
기본 틀을 마련하고 그래프 격자를 구성하는 것까지 앞에서 진행한 실습과 동일합니다.
In [24]:fig=plt.figure() axes1=fig.add_subplot(1,1,1)
4.¶
hist 메서드에 total_bill열을 전달하면 히스토그램이 만들어집니다. 이때 x축의 간격은 bins 인잣값으로 조정할 수 있습니다. bins 인잣값을 10으로 지정하면 x축의 간격을 10으로 조정할 수 있습니다. 나머지는 그래프의 제목과 x,y축의 제목을 추가하는 코드입니다.
In [94]:axes1.hist(tips['total_bill'], bins=10) axes1.set_title('Histogram of Total Bill') axes1.set_xlabel('Frequency') axes1.set_ylabel('Total Bill') fig
Out[94]:<seaborn.axisgrid.PairGrid at 0x7fa89da5c640>
5.¶
이번에는 산점도 그래프를 그려보겠습니다. 산점도 그래프는 변수 2개를 사용해서 만드는 그래프이며 변수 2개를 사용하기 때문에 통계 용어로'이변량 그래프'라고 부릅니다. 다음은 total_bill 열에 따른 tip 열의 분포를 나타낸 산점도 그래프입니다.
6.¶
기본 특과 그래프 격자를 만들고 scatter 메서드에 total_bill, tips 열을 전달하면 산점도 그래프가 나타납니다.
In [92]:scatter_plot=plt.figure() axes1=scatter_plot.add_subplot(1,1,1) axes1.scatter(tips['total_bill'],tips['tip']) axes1.set_title('Scatterplot of Total Bill vs Tip') axes1.set_xlabel('Total Bill') axes1.set_ylabel('Tip')
Out[92]:Text(0, 0.5, 'Tip')
7.¶
이번에는 박스 그래프를 그려보겠습니다. 박스 그래프는 이산형 변수와 연속형 변수를 함께 사용하는 그래프입니다. 이산형 변수란 Female, Male과 같이 명확하게 구분되는 값을 의미하고, 연속형 변수란 Tip과 같이 명확하게 셀 수 없는 범위의 값을 의미합니다.
8.¶
boxplot 메서드를 사용하면 박스 그래프를 그릴 수 있습니다. boxplot 메서드의 첫 번째 인자로 전달하는 값이 조금 복작해 보이죠? tips 데이터프레임에서 성별이 Female인 데이터와Male인 데이터에서 tip 열 데이터만 추출하여 리스트에 담아 전달한 것입니다. 두번째 인자에는 labels 인잣값으로 성별을 구분하기 위한 이름을 추가합니다.
In [91]:boxplot=plt.figure() axes1=boxplot.add_subplot(1,1,1) axes1.boxplot([tips[tips['sex']=='Female']['tip'], tips[tips['sex']=='Male']['tip']], labels=['Female', 'Male']) axes1.set_xlabel('sex') axes1.set_ylabel('Tip') axes1.set_title('Boxplot of Tips by sex')
Out[91]:Text(0.5, 1.0, 'Boxplot of Tips by sex')
다변량 그래프 그리기¶
앞에서 2개의 변수를 사용한 그래프를 이변량 그래프라고 했습니다. 그러면 3개 이상의 변수를 사용한 그래프는 무엇이라고 할까요? 바로 '다변량 그래프'라고 부릅니다. 그러면 다변량 그래프가 왜 필요할까요? 이번에는 다변량 그래프가 왜 필요한지 알아보겠습니다.
다변량 그래프가 필요한 이유¶
앞에서 지불 금액과 팁만을 사용하여 산점도 그래프를 그렸습니다. 만약 여기에 성별을 추가하여 산점도 그래프를 표현하려면 어떻게 해야 할까요? 점의 색상을 다르게 하면 됩니다. 만약 식사 비용을 추가한다면 점의 크기를 다르게 하는 방법으로 산점도 그래프를 표현할 수 있습니다. 이렇게 3개 이상의 변수를 사용하는 다변량 그래프는 적재적소에 맞는 그래프 요소를 추가하여 그래프를 표현해야 합니다.
In [47]:def recode_sex(sex): if sex == 'Female': return 0 else: return 1
2.¶
이제 recode_sex 메서드가 반환값을 데이터프레임에 추가하면 됩니다. 다음은 recode_sex 함수가 반환한 값을 데이터프레임에 sex_color열을 새로 생성하여 추가한 것입니다. 이때 sex 열에 recode_sex 함수를 브로드캐스팅하기 위하여 apply 메서드를 사용했습니다.
In [29]:tips['sex_color']=tips['sex'].apply(recode_sex)
3.¶
그래프를 그리는 김에 테이블당 인원 수도 산점도 그래프에 추가해 볼까요? 테이블당 인원 수는 점의 크기로 표현하면 적당합니다. 다음은 scatter 메서드에 s,c 인잣값으로 테이블당 인원 수와 성별의 치환값을 전달한 것입니다.
In [30]:scatter_plot=plt.figure() axes1=scatter_plot.add_subplot(1,1,1) axes1.scatter( x=tips['total_bill'], y=tips['tip'], s=tips['size']*10, c=tips['sex_color'], alpha=0.5) axes1.set_title('Total Bill vs Tip Colored bu Sex and Sized by Suze') axes1.set_xlabel('Total Bill') axes1.set_ylabel('Tip')
Out[30]:Text(0, 0.5, 'Tip')
04-3 seaborn 라이브러리 자유자재로 사용하기¶
04-2에서는 seaborn 라이브러리의 tips 데이터 집합만 사용했지만 이번에는 seaborn 라이브러리 자체를 활용하여 그래프도 그려보겠습니다. seaborn 라이브러리를 활용하면 matplotlib보다 좀 더 화려한 그래프를 그릴 수 있습니다.
In [5]:import seaborn as sns tips=sns.load_dataset("tips")
2.¶
seaborn 라이브러리로 히스토그램을 그리려면 subplotsm distplot 메서드를 사용하면 됩니다. 먼저 subplots 메서드로 기본 틀을 만들고 distplot 메서드에 total_bill 열 데이터를 전달하면 히스토그램을 그릴 수 있습니다.
In [90]:ax=plt.subplots() ax=sns.distplot(tips['total_bill']) ax.set_title('Total Bill Histogram with Density plot')
Out[90]:Text(0.5, 1.0, 'Total Bill Histogram with Density plot')
3.¶
이때 distplot 메서드를 사용하면 히스토그램과 밀집도 그래프를 같이 그립니다. 만약 밀집도 그래프를 제외하고 싶다면 kde 인잣값을 False로 설정하면 됩니다.
In [89]:ax=plt.subplots() ax=sns.distplot(tips['total_bill'], kde=False) ax.set_title('Total Bill Histogram') ax.set_xlabel('Total Bill') ax.set_ylabel('Frequency')
/home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2557: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms). warnings.warn(msg, FutureWarning)
Out[89]:Text(0, 0.5, 'Frequency')
4.¶
밀집도 그래프만 나타내려면 hist인자를 False로 지정하면 됩니다
In [88]:ax=plt.subplots() ax=sns.distplot(tips['total_bill'], hist=False) ax.set_title('Total Bill Density') ax.set_xlabel('Total Bill') ax.set_ylabel('Unit Probability')
/home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2557: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `kdeplot` (an axes-level function for kernel density plots). warnings.warn(msg, FutureWarning)
Out[88]:Text(0, 0.5, 'Unit Probability')
5.¶
실무 환경에서는 데이터 시각화를 더 효율적으로 하기 위해 여러 그래프를 한 번에 출력하는 경우가 많습니다. 다음은 히스토그램과 밀집도를 그리는 distplot메서드에 rug인자를 추가하여 양탄자 그래프까지 그린 것입니다.
In [87]:ax=plt.subplots() ax=sns.distplot(tips['total_bill'], rug=True) ax.set_title('Total Bill Histogram with Density and Rug Plot') ax.set_xlabel('Total Bill')
/home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2557: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms). warnings.warn(msg, FutureWarning) /home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2056: FutureWarning: The `axis` variable is no longer used and will be removed. Instead, assign variables directly to `x` or `y`. warnings.warn(msg, FutureWarning)
Out[87]:Text(0.5, 0, 'Total Bill')
6.¶
이번에는 히스토그램과 비슷하게 생긴 count 그래프를 그려보겠습니다. count 그래프는 이산값을 나타낸 그래프입니다. 다음은 sountplot 메서드에 tips 데이터프레임의 day열 데이터를 넣어 count 그래프를 그린 것입니다.
In [86]:ax=plt.subplots() ax=sns.countplot('day', data=tips) ax.set_title('Count of days') ax.set_xlabel('Day of the Week') ax.set_ylabel('Frequency')
/home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/_decorators.py:36: FutureWarning: Pass the following variable as a keyword arg: x. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation. warnings.warn(
Out[86]:Text(0, 0.5, 'Frequency')
In [85]:ax=plt.subplots() ax=sns.regplot(x='total_bill', y='tip', data=tips) ax.set_title('Scatterplot of Total Bill and Tip') ax.set_xlabel('Total Bill') ax.set_ylabel('Tip')
Out[85]:Text(0, 0.5, 'Tip')
In [84]:ax=plt.subplots() ax=sns.regplot(x='total_bill', y='tip', data=tips, fit_reg=False) ax.set_title('Scatterplot of Total Bill and Tip') ax.set_xlabel('Total Bill') ax.set_ylabel('Tip')
Out[84]:Text(0, 0.5, 'Tip')
2.¶
이번에는 삼점도 그래프와 히스토그램을 한 번에 그려주는 jointplot 메서드를 사용해 보겠습니다. x,y 인자에 원하는 열 이름을 지정하고 data인잣값으로 데이터프레임을 지정하면 그래프를 그릴 수 있습니다.
In [83]:joint=sns.jointplot(x='total_bill', y='tip', data=tips) joint.set_axis_labels(xlabel='Total Bill', ylabel='Tip') joint.fig.suptitle('Joint Plot of Total Bill and Tip', fontsize=10,y=1.03)
/home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/axisgrid.py:1598: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`). f = plt.figure(figsize=(height, height))
Out[83]:Text(0.5, 1.03, 'Joint Plot of Total Bill and Tip')
3.¶
산점도 그래프는 점이 겹쳐 보일 경우 점을 구분하기 어렵다는 단점이 있습니다. 만약 산점도 그래프의 데이터를 구분하기 쉽게 그리고 싶다면 육각 그래프를 사용하면 됩니다. 육각 그래프는 2차원 표면에 육각형으로 데이터를 쌓아 표현하는 그래프입니다. 그래서 특정 데이터의 개수가 많아지면 점점 진한 색으로 표현됩니다. 육각 그래프는 과정 2에서 사용한 jointplot 메서드를 그대로 사용합니다. 대신 kind 인잣값을 hex로 지정하면 됩니다.
In [82]:hexbin=sns.jointplot(x="total_bill", y="tip", data=tips, kind="hex") hexbin.set_axis_labels(xlabel='Total Bill', ylabel='Tip') hexbin.fig.suptitle('Hexbin Joint Plot of Total Bill and Tip', fontsize=10,y=1.03)
Out[82]:Text(0.5, 1.03, 'Hexbin Joint Plot of Total Bill and Tip')
4. 이차원 밀집도 그리기¶
이번에는 이차원 밀집도를 그려볼까요? 이치원 밀집도는 kdeplot 메서드로 만들 수 있습니다. 다음은 total_bill, tip 열 데이터를 전달하여 이차원 밀집도를 그린 것입니다. 이때 shade 인잣값을 True로 지정하면 그래프에 음영 효과를 줄 수 있습니다.
In [81]:ax=plt.subplots() ax=sns.kdeplot(data=tips['total_bill'], data2=tips['tip'], shade=True) ax.set_title('Kernel Density Plot of Total Bill and Tip') ax.set_xlabel('Total Bill') ax.set_ylabel('Tip')
/home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:1639: FutureWarning: Use `x` and `y` rather than `data` `and `data2` warnings.warn(msg, FutureWarning)
Out[81]:Text(0, 0.5, 'Tip')
5. 바 그래프 그리기¶
이번에는 바 그래프를 그려보겠습니다. 바 그래프는 지정한 변수의 평균을 계산하여 그릴수 있습니다. 다음은 시간에 따라 지불한 비용의 평균을 바 그래프로 나타낸 것입니다.
In [80]:ax=plt.subplots() ax=sns.barplot(x='time', y='total_bill', data=tips) ax.set_title('Bar plot of average total bill for time of day') ax.set_xlabel('Time of day') ax.set_ylabel('Average total bill')
Out[80]:Text(0, 0.5, 'Average total bill')
6. 박스 그래프 그리기¶
박스 그래프도 그려보겠습니다. 박스 그래프는 최솟값, 1분위수, 중간값, 3분위수, 최대값, 이상치 등 다양한 통계량을 한 번에 표현하는 그래프입니다.
In [79]:ax=plt.subplots() ax=sns.boxplot(x='time', y='total_bill', data=tips) ax.set_title('Boxplot of total bill by time of day') ax.set_xlabel('Time of day') ax.set_ylabel('Total Bill')
Out[79]:Text(0, 0.5, 'Total Bill')
7.¶
박스 그래프는 다양한 통계 수치를 확인하기 위해 자주 사용하는 그래프지만 데이터분산이 모호하게 표현됩니다. 이런 경우에는 박스 그래프에 커널 밀도를 추정한 바이올린 그래프를 사용하면 됩니다. 쉽게 말해 과정 6의 박스 형태를 바이올린 형태로 바꾸면 바이올린 그래프가 됩니다. 바이올린 그래프는 violintplot 메서드를 사용하여 그릴 수 있습니다.
In [78]:ax=plt.subplots() ax=sns.violinplot(x='time', y='total_bill', data=tips) ax.set_title('Violin plot of total bill by time of day') ax.set_xlabel('Time of day') ax.set_ylabel('Total Bill')
Out[78]:Text(0, 0.5, 'Total Bill')
8. 관계 그래프 그리기¶
마지막으로 관계 그래프를 그려보겠습니다. 관계 그래프는 지금까지 설명한 그래프를 종합한 그래프라고 생각하면 됩니다. 관계 그래프는 pairplot 메서드에 데이터프레임을 넣는 방법으로 간단하게 그릴 수 있습니다.
In [77]:fig=sns.pairplot(tips)
9.¶
이때 관계 그래프는 중복된 정보가 표현된다는 단점이 있습니다. 즉, 관계 그래프의 절반은 나머지 절반과 같습니다. 이런 경우에는 중복된 그래프가 그려지는 위치를 직접 지정하여 원하는 그래프로 교체하면 됩니다.
map_upper 메서드는 대각선을 기준으로 위쪽에 그릴 그래프를 지정합니다. 반대로 map_lower 메서드는 대각선을 기준으로 아래쪽에 그릴 그래프를 지정합니다. map_diag는 대각선을 중심으로 그래프를 그립니다. 다음은 이차원 밀집도를 대각선 기준으로 아래쪽에, 산점도 그래프는 대각선 기준으로 위쪽에 그린 것입니다. 히스토그램과 밀집도는 대각선을 중심으로 그려집니다.
In [76]:pair_grid=sns.PairGrid(tips) pair_grid=pair_grid.map_upper(sns.regplot) pair_grid=pair_grid.map_lower(sns.kdeplot) pair_grid=pair_grid.map_diag(sns.distplot, rug=True) plt.show()
/home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2557: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms). warnings.warn(msg, FutureWarning) /home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2056: FutureWarning: The `axis` variable is no longer used and will be removed. Instead, assign variables directly to `x` or `y`. warnings.warn(msg, FutureWarning) /home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2557: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms). warnings.warn(msg, FutureWarning) /home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2056: FutureWarning: The `axis` variable is no longer used and will be removed. Instead, assign variables directly to `x` or `y`. warnings.warn(msg, FutureWarning) /home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2557: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms). warnings.warn(msg, FutureWarning) /home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2056: FutureWarning: The `axis` variable is no longer used and will be removed. Instead, assign variables directly to `x` or `y`. warnings.warn(msg, FutureWarning)
In [75]:ax=plt.subplots() ax=sns.violinplot(x='time', y='total_bill', hue='sex', data=tips, split=True)
2. 산점도, 관계 그래프 그리기 --색상추가¶
산점도 그래프, 관계 그래프를 그리는 경우에는 마찬가지 방법으로 색상을 추가할 수 있습니다.
In [68]:scatter=sns.lmplot(x='total_bill', y='tip', data=tips, hue='sex', fit_reg=False)
In [69]:fig=sns.pairplot(tips, hue='sex')
3. 산점도 그래프의 크기와 모양 조절하기¶
이번에는 산점도 그래프의 크기와 모양을 조절해 보겠습니다.다음은 산점도 그래프의 점 크기를 조절하여 표현한 것입니다. 산점도 그래프의 점 크기를 조절하려면 scatter_kws에 딕셔너리 형태로 인잣값을 전달하면 됩니다. 여기서는 크기만 조절하기 위해 's':tips['size']를 딕셔너리에 담아 전달했습니다.
scatter=sns.lmplot(x='total_bill', y='tip', data=tips, fit_reg=False, hue='sex',scatter_kws={'s':tips['size']*10})
4.¶
만약 산점도 그래프의 점을 다른 기호로 표현하고 싶다면 markers 인잣값에 표현하고자 하는 기호를 리스트에 담아 전달하면 됩니다.
scatter=sns.lmplot(x='total_bill', y='tip', data=tips, fit_reg=False, hue='sex', markers=['o','x'], scatter_kws={'s': tips['size']*10})
5. implot 메서드로 4개의 데이터 그룹에 대한 그래프 한 번에 그리기¶
다음은 앤스콤 4분할 그래프를 Implot 메서드로 그린 것입니다. x와 y인자에는 앤스콤 데이터 집합의 x,y 열을 전달하고 data 인자에는 데이터프레임을 전달했습니다. 그런데 그래프를 자세히 살펴보면 4개의 데이터 그룹이 한꺼번에 산점도 그래프로 그려진 것을 알 수 있습니다. 그룹별로 그래프를 나누어 그리려면 어떻게 해야할까요?
In [72]:anscombe_plot=sns.lmplot(x='x', y='y', data=anscombe, fit_reg=False)
6.¶
그룹별로 그래프를 나누어 그리려면 Implot 메서드에 추가로 col,col_warp 인자를 설정해야 합니다. 다음은 Implot 메서드를 사용해 데이터 그룹별로 그래프를 그린 것입니다. col_wrap 인자에 그래프를 그릴 열의 최대값을 지정하고 col인자에는 데이터 그룹을 구분할 열을 지정했습니다.
In [6]:anscombe_plot=sns.lmplot(x='x',y='y', data=anscombe, fit_reg=False, col='dataset', col_wrap=2)
FacetGrid 클래스로도 그룹별 그래프를 그릴 수 있습니다.¶
만약 Implot 메서드를 사용하는 방법이 복잡하게 느껴진다면 FacetGrid 클래스를 사용하여 간편하게 그래프를 그릴 수도 있습니다. 이번에는 tips 데이터 집합을 사용하여 그래프를 그려보겠습니다.
1.¶
먼저 FacetGrid에 데이터프레임과 그룹을 구분할 열 이름을 전달하여 객체를 생성합니다. 그런다음 객체의 map 메서드에 그래프의 종류와 x축으로 지정할 열 이름을 순서대로 전달하면 히스토그램, 밀집도, 양탄자 그래프를 그릴 수 있습니다.
In [111]:facet=sns.FacetGrid(tips, col='time') facet.map(sns.distplot, 'total_bill', rug=True)
/home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2557: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms). warnings.warn(msg, FutureWarning) /home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2056: FutureWarning: The `axis` variable is no longer used and will be removed. Instead, assign variables directly to `x` or `y`. warnings.warn(msg, FutureWarning) /home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2557: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms). warnings.warn(msg, FutureWarning) /home/dmlrkd67/anaconda3/lib/python3.8/site-packages/seaborn/distributions.py:2056: FutureWarning: The `axis` variable is no longer used and will be removed. Instead, assign variables directly to `x` or `y`. warnings.warn(msg, FutureWarning)
Out[111]:<seaborn.axisgrid.FacetGrid at 0x7fa8ac5afdc0>
2.¶
다변량 그래프도 그려볼까요? 다음은 tips 데이터 집합의 day 열로 그룹을 구분하여 그래프를 그린것입니다.
In [112]:facet=sns.FacetGrid(tips, col='day', hue='sex') facet=facet.map(plt.scatter, 'total_bill', 'tip') facet=facet.add_legend()
3.¶
이번에는 더 많은 변수를 사용하여 그래프를 그려보겠습니다. 다음은 time, smoker 열을 사용하여 산점도 그래프를 그린 것입니다. time, smoker 열은 각각 2개의 값을 가지고 있습니다. 따라서 2행 2열의 격자가 만들어집니다.
In [113]:facet=sns.FacetGrid(tips, col='time', row='smoker', hue='sex') facet.map(plt.scatter,'total_bill', 'tip')
Out[113]:<seaborn.axisgrid.FacetGrid at 0x7fa8acc95490>
04-4 데이터프레임과 시리즈로 그래프 그리기¶
데이터프레임과 시리즈로도 그래프를 그릴 수 있습니다. 간편하게 그래프를 그리고 싶은 경우에는 데이터프레임이나 시리즈를 사용하여 바로 그래프를 그릴 수 있습니다.
In [114]:ax=plt.subplots() ax=tips['total_bill'].plot.hist()
2.¶
투명도를 조절하려면 hist 메서드의 alpha, bin, ax 인자를 사용하면 됩니다. 다음은 tips 데이터프레임에서 2개의 시리즈를 선택하여 히스토그램을 그린 것입니다.
In [115]:fig, ax=plt.subplots() ax=tips[['total_bill', 'tip']].plot.hist (alpha=0.5, bins=20, ax=ax)
3.¶
밀집도, 산점도 그래프, 육각 그래프는 각각 kde, scatter, hexbin 메서드를 사용하여 그릴 수 있습니다.
In [116]:ax=plt.subplots() ax=tips['tip'].plot.kde()
In [117]:fig, ax=plt.subplots() ax=tips.plot.scatter(x='total_bill', y='tip', ax=ax)
In [119]:fig, ax=plt.subplots() ax=tips.plot.hexbin(x='total_bill', y='tip', ax=ax)
4.¶
이때 육각 그래프의 육각형 크기는 gridsize 인자를 사용하여 변경할 수 있습니다.
In [122]:fig, ax= plt.subplots() ax=tips.plot.hexbin(x='total_bill', y='tip', gridsize=10, ax=ax)
5.¶
다음은 box 메서드를 사용하여 그린 박스 그래프입니다.
In [123]:fig, ax= plt.subplots() ax=tips.plot.box(ax=ax)
04-5 seaborn 라이브러리로 그래프 스타일 설정하기¶
seaborn 라이브러리로 만든 그래프는 모두 기본 스타일이었습니다. seaborn 라이브러리로 만든 그래프의 스타일은 set+style 메서드를 사용하여 바꿀 수 있습니다. set_style은 스타일을 적용할 부분에서 한 번만 실행하면 됩니다. 그러면 메서드를 실행한 이후의 그래프가 모두 지정한 스타일로 바뀝니다. 다음 예제를 통해 스타일 설정 방법을 간한히 알아볼까요?
그래프 스타일 적용하기¶
In [126]:fig, ax= plt.subplots() ax=sns.violinplot(x='time', y='total_bill', hue='sex', data=tips, split=True)
2.¶
whitegrid로 스타일을 설정하여 그래프를 그리면 어떻게 될까요? 그래프의 배경에 가로 줄이 생겼습니다
In [127]:sns.set_style('whitegrid') fig, ax=plt.subplots() ax=sns.violinplot(x='time', y='total_bill', hue='sex', data=tips, split=True)
3.¶
다음은 for문을 이용하여 모든 스타일을 하나씩 적용한 그래프입니다.
In [129]:fig=plt.figure() seaborn_styles=['darkgrid', 'whitegrid', 'dark', 'white', 'ticks'] for idx, style in enumerate(seaborn_styles): plot_position=idx+1 with sns.axes_style(style): ax=fig.add_subplot(2,3,plot_position) violin=sns.violinplot(x='time', y='total_bill', data=tips, ax=ax) violin.set_title(style) fig.tight_layout()
마무리하며¶
이 장에서는 다양한 그래프를 그리는 방법에 대해 알아보았습니다. 데이터 시각화는 데이터를 분석하기 위해 반드시 알아야 하는 중용한 요소입니다. 앞으로는 좀 더 복잡한 형태의 그래프들이 나오므로 이번 장의 실습 내용을 반드시 익힌 후에 다음 장으로 넘어가기 바랍니다. 더 많은 정보를 알고 싶다면 구글에 seaborn documentation 이나 matplotlib documentation을 검색하여 나오는 공식 문서를 참고하세요.
출처 : "do it 데이터 분석을 위한 판다스 입문"
'판다스' 카테고리의 다른 글
chapter-7 깔끔한 데이터 (0) 2021.09.23 chapter-6 누락값 처리하기 (0) 2021.09.23 chapter-03 판다스 데이터프레임과 시리즈 (0) 2021.09.17 chapter-5 데이터 연결하기 (0) 2021.09.17 chapter-2 판다스 시작하기 (0) 2021.09.14 -