<안내>
필자도 배우는 입장이라 틀린점, 잘못된 점이 있을 수 있습니다.
그러니 지적, 피드백 환영합니다.

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)법은 시계열 데이터를 표현하는 데에 많이 사용하는 방법 중 하나입니다.

접근

  1. 일단 데이터를 열어서
  2. 시간을 x 축으로 , 가격을 y축으로 잡고
  3. 데이터 유형에 알맞는 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

오늘 배운 것

  1. Matplotlib 이용해서 그래프 만들기
  2. Matplitlib의 다양한 plot 살펴봄
  3. Seaborn 라이브러리의 plot 살펴봄
  4. 각 라이브러리의 다양한 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