<안내>
필자도 배우는 입장이라 틀린점, 잘못된 점이 있을 수 있습니다.
그러니 지적, 피드백 환영합니다.
Matplotlib으로 데이터 시각화하기¶
데이터를 보기좋게 표현해봅시다.
1. Matplotlib 시작하기¶
2. 자주 사용되는 Plotting의 Options¶
- 크기 :
figsize
- 제목 :
title
- 라벨 :
_label
- 눈금 :
_ticks
- 범례 :
legend
3. Matplotlib Case Study¶
- 꺾은선 그래프 (Plot)
- 산점도 (Scatter Plot)
- 박스그림 (Box Plot)
- 막대그래프 (Bar Chart)
- 원형그래프 (Pie Chart)
4. The 멋진 그래프, seaborn Case Study¶
- 커널밀도그림 (Kernel Density Plot)
- 카운트그림 (Count Plot)
- 캣그림 (Cat Plot)
- 스트립그림 (Strip Plot)
- 히트맵 (Heatmap)
I. Matplotlib 시작하기¶
- 파이썬의 데이터 시각화 라이브러리(라이브러리 - 코드의 모임)
cf) 라이브러리 vs 프레임워크
개발자들이 만들어놓은 코드, 우리가 코드를 더 작성해서 원하는 일을 함
프레임워크 : 틀이 짜여있고 데이터만 넣으면 됨
- matplotlib
%matplotlib inline
을 통해서 활성화
In [1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
II. Matplotlib Case Study with Arguments¶
In [2]:
plt.plot([1,2,3,4,5]) # 실제 plotting을 하는 함수 # y = x + 1 그래프
# x값을 명시하지않으면 인덱스를 기준으로 만듬
plt.show() # plt를 확인하는 명령
In [3]:
plt.plot([2,4,2,4,2])
plt.show()
Figsize : Figure(도면)의 크기 조절¶
In [4]:
plt.figure(figsize=(3,3)) # potting을 할 도면을 선언
plt.plot([0,1,2,3,4])
plt.show()
2차함수 그래프 with plot()¶
In [5]:
plt.plot([0,1,2,3,4])
plt.show()
In [6]:
# numpy.array를 이용해서 함수 그래프 만들기
# y = x^2
x = np.array([1,2,3,4,5]) # 정의역
y = np.array([1,4,9,16,25]) # f(x)
plt.plot(x,y)
plt.show()
In [7]:
# np.arange(a,b,c) # range에선 -10~10 : c // 1,2 이런식이었는데,
# arange에선 c = 실수범위로 가능함
x = np.arange(-10, 10, 0.01)
plt.plot(x,x**2)
plt.show()
In [8]:
# x, y축에 설명 추가하기
x = np.arange(-10, 10, 0.01)
###
plt.xlabel("x value")
plt.ylabel("f(x) value")
###
plt.plot(x,x**2)
plt.show()
In [9]:
# x, y축의 범위 설정하기
x = np.arange(-10, 10, 0.01)
plt.xlabel("x value")
plt.ylabel("f(x) value")
###
plt.axis([-5,5, 0, 25]) # 축 함수[x_min,x_max, y_min, y_max]
###
plt.plot(x,x**2)
plt.show()
In [10]:
# x, y축에 눈금 설정하기
x = np.arange(-10, 10, 0.01)
plt.xlabel("x value")
plt.ylabel("f(x) value")
plt.axis([-5,5, 0, 25]) # 축 함수[x_min,x_max, y_min, y_max]
plt.xticks([i for i in range(-5,5+1,1)])
plt.yticks([i for i in range(0,24+1,3)])
plt.plot(x,x**2)
plt.show()
In [11]:
# 그래프에 title 달기
x = np.arange(-10, 10, 0.01)
plt.xlabel("x value")
plt.ylabel("f(x) value")
plt.axis([-5,5, 0, 25]) # 축 함수[x_min,x_max, y_min, y_max]
plt.xticks([i for i in range(-5,5+1,1)])
plt.yticks([i for i in range(0,24+1,3)])
###
plt.title("y = x^2 graph")
###
plt.plot(x,x**2)
plt.show()
In [12]:
# legend 달기
x = np.arange(-10, 10, 0.01)
plt.xlabel("x value")
plt.ylabel("f(x) value")
plt.axis([-5,5, 0, 25]) # 축 함수[x_min,x_max, y_min, y_max]
plt.xticks([i for i in range(-5,5+1,1)])
plt.yticks([i for i in range(0,24+1,3)])
plt.title("y = x^2 graph")
###
plt.plot(x,x**2, label = 'trend')
plt.legend()
###
plt.plot(x,x**2)
plt.show()
III. Matplotlib Case Study¶
꺾은선 그래프 (Plot)¶
plot()
In [13]:
x = np.arange(20) # 0~19
y = np.random.randint(0,20,20)
plt.axis([0,20,0,20])
###
plt.yticks([i for i in range(0,20+1,5)])
###
plt.plot(x,y)
plt.show()
# Extra : y축을 20까지 보이게 하고싶다면? , y축을 5단위로 보이게 하고싶다면?
Plot vs scatterl plot¶
꺽: 시계열 데이터 (시간에 따라) 변하는 걸 보기 좋음
scatter :서로 별개인 것 같은 두 변수
산점도 (Scatter Plot)¶
scatter()
- 변수를 점만 통통통 찍어놓음
In [14]:
plt.scatter(x,y)
plt.show()
박스 그림 (Box Plot)¶
plt.boxplot()
- 수치형 데이터에 대한 정보(Q1, Q2, Q3, min, max)
In [15]:
plt.boxplot((x,y))
# Q1 :25 % Q2:상위 50% median 중앙값 Q3: 75%
###
plt.title('Box plot of x, y')
###
plt.show() # ??? 이거 주식 그래프잖아 ㅋㅋ
# Extra : Plot의 Title을 "Box plot of y" 라고 하자
막대 그래프 (Bar Plot)¶
plt.bar()
- 범주형 데이터의 '값'과 그 값의 크기를 직사각형으로 나타낸 그림
In [16]:
plt.bar (x,y)
plt.xticks(np.arange(0,20,1))
plt.show()
# Extra : xticks를 올바르게 설정해보자
Histogram¶
hist()
- 도수분표를 직사각형의 막대 형태로 나타냈다.
- "계급" 이라는 개념이 들어간다.
- 변량을 그룹화 해서 나타내면 좋지 않을까? 라는 생각에서 표현을 하게됨
- 0, 1, 2가 아니라 , 0~2 까지의 범주형 데이터로 구성후 그림을 그림
In [17]:
plt.hist(y,bins= np.arange(0,22,2)) # bins 범주의 간격을 표현
###
plt.xticks(np.arange(0,22,2))
###
plt.show()
# Extra : xticks를 올바르게 고쳐보자
#
원형 그래프 (Pie Chart)¶
- 데이터에서 전체에 대한 부분의 비율을 부채꼴로 나타낸 그래프
- 다른 그래프에 비해서 비율 확인에 용이
.pie()
In [18]:
z = [100, 200, 300, 400]
plt.pie(z, labels=['one','two','three','four'])
plt.show() # pie 차트는 라벨을 붙여주는게 무적권 좋음
IV. The 멋진 그래프, Seaborn Case Study¶
Matplotlib를 기반으로 더 다양한 시각화 방법을 제공하는 라이브러리¶
- 커널밀도그림 (Kernel Density Plot)
- 카운트그림 (Count Plot)
- 캣그림 (Cat Plot)
- 스트립그림 (Strip Plot)
- 히트맵 (Heatmap)
Seaborn Import 하기¶
In [19]:
import seaborn as sns
커널밀도그림 (Kernel Density Plot)¶
- 히스토그램과 같은 연속적인 분포를 곡선화해서 그린 그림
sns.kdeplot()
In [20]:
# in Histogram
x = np.arange(0,22,2)
y = np.random.randint(0,20,20)
plt.hist(y,bins =x)
plt.show()
In [21]:
# kdeplot
sns.kdeplot(y, shade = True) # shade : 밑에 색칠해줌 default = False
plt.show()
카운트 그림 (Count Plot)¶
- 범주형 column의 빈도수를 시각화 -> Groupby 후의 도수를 하는 것과 동일한 효과
sns.countplot()
In [22]:
vote_df = pd.DataFrame({'name':['Andy', 'Bob', 'Cat'], 'vote': [True, True, False]})
vote_df
Out[22]:
name | vote | |
---|---|---|
0 | Andy | True |
1 | Bob | True |
2 | Cat | False |
In [23]:
# in matplotlib barplot
vote_count = vote_df.groupby('vote').count()
vote_count
Out[23]:
name | |
---|---|
vote | |
False | 1 |
True | 2 |
In [24]:
plt.bar(x=[False,True],height = vote_count['name'])
plt.show()
In [25]:
# sns의 countplot
sns.countplot(x = vote_df['vote'])
plt.show()
캣그림 (Cat Plot)¶
- 숫자형 변수와 하나 이상의 범주형 변수의 관계를 보여주는 함수
sns.catplot()
In [26]:
covid = pd.read_csv('./country_wise_latest.csv')
covid.head(5)
Out[26]:
Country/Region | Confirmed | Deaths | Recovered | Active | New cases | New deaths | New recovered | Deaths / 100 Cases | Recovered / 100 Cases | Deaths / 100 Recovered | Confirmed last week | 1 week change | 1 week % increase | WHO Region | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Afghanistan | 36263 | 1269 | 25198 | 9796 | 106 | 10 | 18 | 3.50 | 69.49 | 5.04 | 35526 | 737 | 2.07 | Eastern Mediterranean |
1 | Albania | 4880 | 144 | 2745 | 1991 | 117 | 6 | 63 | 2.95 | 56.25 | 5.25 | 4171 | 709 | 17.00 | Europe |
2 | Algeria | 27973 | 1163 | 18837 | 7973 | 616 | 8 | 749 | 4.16 | 67.34 | 6.17 | 23691 | 4282 | 18.07 | Africa |
3 | Andorra | 907 | 52 | 803 | 52 | 10 | 0 | 0 | 5.73 | 88.53 | 6.48 | 884 | 23 | 2.60 | Europe |
4 | Angola | 950 | 41 | 242 | 667 | 18 | 1 | 0 | 4.32 | 25.47 | 16.94 | 749 | 201 | 26.84 | Africa |
In [27]:
s = sns.catplot(x='WHO Region' , y='Confirmed' , data = covid)
s.fig.set_size_inches(10,6) # x축 길이 , y축 길이 kind = default: strip
plt.show()
스트립 그림(Strip Plot)¶
- scatter plot과 유사하게 데이터와 수치를 표현하는 그래프
sns.stripplot()
In [28]:
sns.stripplot (x='WHO Region' , y='Recovered' , data=covid)
plt.show()
Swarm Plot¶
- strip과 다르게, 유사한 애들이 겹치는 경우 양 옆으로 분산해줌
swarmplot()
In [29]:
s= sns.swarmplot (x='WHO Region' , y='Recovered' , data=covid)
plt.show()
c:\python39\lib\site-packages\seaborn\categorical.py:1296: UserWarning: 22.7% of the points cannot be placed; you may want to decrease the size of the markers or use stripplot.
warnings.warn(msg, UserWarning)
c:\python39\lib\site-packages\seaborn\categorical.py:1296: UserWarning: 69.6% of the points cannot be placed; you may want to decrease the size of the markers or use stripplot.
warnings.warn(msg, UserWarning)
c:\python39\lib\site-packages\seaborn\categorical.py:1296: UserWarning: 79.2% of the points cannot be placed; you may want to decrease the size of the markers or use stripplot.
warnings.warn(msg, UserWarning)
c:\python39\lib\site-packages\seaborn\categorical.py:1296: UserWarning: 54.3% of the points cannot be placed; you may want to decrease the size of the markers or use stripplot.
warnings.warn(msg, UserWarning)
c:\python39\lib\site-packages\seaborn\categorical.py:1296: UserWarning: 31.2% of the points cannot be placed; you may want to decrease the size of the markers or use stripplot.
warnings.warn(msg, UserWarning)
히트맵(Heatmap)¶
- 데이터의 행렬을 색상으로 표현해주는 그림
sns.heatmap(원하는 데이터 이름)
In [30]:
# 히트맵 예제
covid.corr() # 행렬꼴로 연관성을 나타냄
Out[30]:
Confirmed | Deaths | Recovered | Active | New cases | New deaths | New recovered | Deaths / 100 Cases | Recovered / 100 Cases | Deaths / 100 Recovered | Confirmed last week | 1 week change | 1 week % increase | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Confirmed | 1.000000 | 0.934698 | 0.906377 | 0.927018 | 0.909720 | 0.871683 | 0.859252 | 0.063550 | -0.064815 | 0.025175 | 0.999127 | 0.954710 | -0.010161 |
Deaths | 0.934698 | 1.000000 | 0.832098 | 0.871586 | 0.806975 | 0.814161 | 0.765114 | 0.251565 | -0.114529 | 0.169006 | 0.939082 | 0.855330 | -0.034708 |
Recovered | 0.906377 | 0.832098 | 1.000000 | 0.682103 | 0.818942 | 0.820338 | 0.919203 | 0.048438 | 0.026610 | -0.027277 | 0.899312 | 0.910013 | -0.013697 |
Active | 0.927018 | 0.871586 | 0.682103 | 1.000000 | 0.851190 | 0.781123 | 0.673887 | 0.054380 | -0.132618 | 0.058386 | 0.931459 | 0.847642 | -0.003752 |
New cases | 0.909720 | 0.806975 | 0.818942 | 0.851190 | 1.000000 | 0.935947 | 0.914765 | 0.020104 | -0.078666 | -0.011637 | 0.896084 | 0.959993 | 0.030791 |
New deaths | 0.871683 | 0.814161 | 0.820338 | 0.781123 | 0.935947 | 1.000000 | 0.889234 | 0.060399 | -0.062792 | -0.020750 | 0.862118 | 0.894915 | 0.025293 |
New recovered | 0.859252 | 0.765114 | 0.919203 | 0.673887 | 0.914765 | 0.889234 | 1.000000 | 0.017090 | -0.024293 | -0.023340 | 0.839692 | 0.954321 | 0.032662 |
Deaths / 100 Cases | 0.063550 | 0.251565 | 0.048438 | 0.054380 | 0.020104 | 0.060399 | 0.017090 | 1.000000 | -0.168920 | 0.334594 | 0.069894 | 0.015095 | -0.134534 |
Recovered / 100 Cases | -0.064815 | -0.114529 | 0.026610 | -0.132618 | -0.078666 | -0.062792 | -0.024293 | -0.168920 | 1.000000 | -0.295381 | -0.064600 | -0.063013 | -0.394254 |
Deaths / 100 Recovered | 0.025175 | 0.169006 | -0.027277 | 0.058386 | -0.011637 | -0.020750 | -0.023340 | 0.334594 | -0.295381 | 1.000000 | 0.030460 | -0.013763 | -0.049083 |
Confirmed last week | 0.999127 | 0.939082 | 0.899312 | 0.931459 | 0.896084 | 0.862118 | 0.839692 | 0.069894 | -0.064600 | 0.030460 | 1.000000 | 0.941448 | -0.015247 |
1 week change | 0.954710 | 0.855330 | 0.910013 | 0.847642 | 0.959993 | 0.894915 | 0.954321 | 0.015095 | -0.063013 | -0.013763 | 0.941448 | 1.000000 | 0.026594 |
1 week % increase | -0.010161 | -0.034708 | -0.013697 | -0.003752 | 0.030791 | 0.025293 | 0.032662 | -0.134534 | -0.394254 | -0.049083 | -0.015247 | 0.026594 | 1.000000 |
In [31]:
sns.heatmap(covid.corr())
Out[31]:
<AxesSubplot:>
Mission: 가즈아! [ 미완성임!!! ]
min값 최고가를 max값, 오픈가격을 q1 종료가격 q3으로 하고싶은데
다음 데이터가 주어졌을 때 2016.6 ~ 2017.6 기간의 5-MA(Moving Average) 비트코인 가격 그래프를 그려주세요.
- 선의 색깔은 노란색(#f2a900) 으로 해야합니다.
- x-axis label과 y-axis label은 적절한 텍스트로 추가되어야 합니다.
- 이동평균의 기준은
Open
Column으로 계산합니다. - 이외에도 그래프를 알아보기 쉽게 하기 위한 정보(Text, Facet 등)을 추가하는 것도 좋습니다.
- 💡 이동평균(Moving Average)법은 시계열 데이터를 표현하는 데에 많이 사용하는 방법 중 하나입니다.
접근¶
- 일단 데이터를 열어서
- 시간을 x 축으로 , 가격을 y축으로 잡고
- 데이터 유형에 알맞는 plot을 골라서 표현하면 되겠네
In [41]:
bitcoin = pd.read_csv('./BitCoin.csv')
bitcoin
Out[41]:
Unnamed: 0 | Date | Open | High | Low | Close | Volume | Market Cap | |
---|---|---|---|---|---|---|---|---|
0 | 0 | 2017-09-22 | 3628.02 | 3758.27 | 3553.53 | 3630.70 | 1.194830e+09 | 60152300000 |
1 | 1 | 2017-09-21 | 3901.47 | 3916.42 | 3613.63 | 3631.04 | 1.411480e+09 | 64677600000 |
2 | 2 | 2017-09-20 | 3916.36 | 4031.39 | 3857.73 | 3905.95 | 1.213830e+09 | 64918500000 |
3 | 3 | 2017-09-19 | 4073.79 | 4094.07 | 3868.87 | 3924.97 | 1.563980e+09 | 67520300000 |
4 | 4 | 2017-09-18 | 3591.09 | 4079.23 | 3591.09 | 4065.20 | 1.943210e+09 | 59514100000 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
1604 | 1604 | 2013-02-05 | 116.38 | 125.60 | 92.28 | 105.21 | 6.722784e+06 | 1292190000 |
1605 | 1605 | 2013-01-05 | 139.00 | 139.89 | 107.72 | 116.99 | 8.026719e+06 | 1542820000 |
1606 | 1606 | 2013-04-30 | 144.00 | 146.93 | 134.05 | 139.00 | 8.312655e+06 | 1597780000 |
1607 | 1607 | 2013-04-29 | 134.44 | 147.49 | 134.00 | 144.54 | 7.757951e+06 | 1491160000 |
1608 | 1608 | 2013-04-28 | 135.30 | 135.98 | 132.10 | 134.21 | 7.806648e+06 | 1500520000 |
1609 rows × 8 columns
In [64]:
date = bitcoin['Date']
date_start = date.get(bitcoin['Date'] == '2016-05-31')
date_start # 2016 05월 31일의 인덱스, 날짜
Out[64]:
479 2016-05-31
Name: Date, dtype: object
In [65]:
date = bitcoin['Date']
date_start = date.get(bitcoin['Date'] == '2016-01-06')
date_start # 2016 06월 01일의 인덱스, 날짜
Out[65]:
478 2016-01-06
Name: Date, dtype: object
In [66]:
date = bitcoin['Date']
date_start = date.get(bitcoin['Date'] == '2016-06-01')
date_start # 2016 01월 06일의 인덱스, 날짜
Out[66]:
625 2016-06-01
Name: Date, dtype: object
In [49]:
date_end = date.get(bitcoin['Date'] == '2017-07-03')
date_end
Out[49]:
199 2017-07-03
Name: Date, dtype: object
In [56]:
bitcoin['']
Out[56]:
Unnamed: 0 | Date | Open | High | Low | Close | Volume | Market Cap | |
---|---|---|---|---|---|---|---|---|
470 | 470 | 2016-09-06 | 582.20 | 582.20 | 570.95 | 574.63 | 71301000.0 | 9103080000 |
471 | 471 | 2016-08-06 | 577.17 | 582.84 | 573.13 | 581.64 | 80265800.0 | 9022250000 |
472 | 472 | 2016-07-06 | 585.45 | 590.26 | 567.51 | 576.60 | 107770000.0 | 9149580000 |
473 | 473 | 2016-06-06 | 574.60 | 586.47 | 574.60 | 585.54 | 72138900.0 | 8977700000 |
474 | 474 | 2016-05-06 | 573.31 | 582.81 | 569.18 | 574.98 | 68874100.0 | 8955060000 |
475 | 475 | 2016-04-06 | 569.71 | 590.13 | 564.24 | 572.73 | 94925300.0 | 8897080000 |
476 | 476 | 2016-03-06 | 537.68 | 574.64 | 536.92 | 569.19 | 122020000.0 | 8395070000 |
477 | 477 | 2016-02-06 | 536.51 | 540.35 | 533.08 | 537.97 | 60378200.0 | 8375000000 |
478 | 478 | 2016-01-06 | 531.11 | 543.08 | 525.64 | 536.92 | 86061800.0 | 8288680000 |
479 | 479 | 2016-05-31 | 534.19 | 546.62 | 520.66 | 531.39 | 138450000.0 | 8335100000 |
480 | 480 | 2016-05-30 | 528.47 | 544.35 | 522.96 | 533.86 | 87958700.0 | 8243960000 |
481 | 481 | 2016-05-29 | 527.48 | 553.96 | 512.18 | 526.23 | 148737000.0 | 8226500000 |
482 | 482 | 2016-05-28 | 473.03 | 533.47 | 472.70 | 530.04 | 181199000.0 | 7375780000 |
483 | 483 | 2016-05-27 | 453.52 | 478.15 | 453.52 | 473.46 | 164781000.0 | 7070010000 |
484 | 484 | 2016-05-26 | 449.67 | 453.64 | 447.90 | 453.38 | 65203800.0 | 7008500000 |
오늘 배운 것
- Matplotlib 이용해서 그래프 만들기
- Matplitlib의 다양한 plot 살펴봄
- Seaborn 라이브러리의 plot 살펴봄
- 각 라이브러리의 다양한 plot 활용해서 정보를 보기 좋게 만들 수있음
더 알고싶은 것.
1. 비트코인 그래프에서 q1 q2 q3을 임의로 어떤 값에 할당할 수 있을까? 할당할 수 있다면, 최저가를 min에, 최고가를 max, q1 ,q3에 종가와 시가 (오른 날에는 종가가 높겠지?)
2. 일단 주말 과제를 주말을 들여서 끝내야함
'TIL > [겨울방학 부트캠프]TIL' 카테고리의 다른 글
TIL 7일차 (22.01.11) (0) | 2022.01.12 |
---|---|
TIL 6일차 (22.01.10) (0) | 2022.01.10 |
TIL 4일차 (22.01.06) (0) | 2022.01.06 |
TIL 3일차 (22.01.05) (0) | 2022.01.05 |
TIL 2일차(22.01.04) (0) | 2022.01.04 |