Data analysis 7 (matplotlib)
Matplotlib
Matplotlib API 개요
- 정보 시각화는 데이터 분석에서 무척 중요
- 시각화는 특잇값을 찾아내거나, 데이터 변형이 필요한지 알아보거나, 모델에 대한 아이디어를 찾기 위한 과정의 일부
-
파이썬 시각화 도구로 matplotlib 활용
- 공식 사이트 https://matplotlib.org/
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.plot([1, 2, 3], [4, 5, 6]) # 각각의 리스트가 x축, y축으로 전달되서 선그래프
plt.title('Hello Plot')
plt.show() # 주피터 노트북에서는 plt.show() 안해줘도 그림이 표시가 되지만, .py 같은 스크립트 작성시에는 필요
Figure와 Axes
from IPython.display import Image
Image('./images/figure_axes.png')
Figure
- 그림을 그리기 위한 도화지의 역할, 그림판의 크기 등을 조절함
Axes
- 실제 그림을 그리는 메소드들과 x축, y축, title 등의 속성을 가짐
plt.plot([1, 2, 3], [4, 5, 6]) # 기본 설정값의 Figure 객체가 만들어진 후, 내부적으로 Axes.plot() 호출
plt.title('Hello Plot') # Axes.set_title() 호출
plt.show() # Figure.show() 호출출
plt.figure(figsize=(10, 4)) # 가로가 10, 세로가 4인 Figure 객체를 생성해서 반환
plt.plot([1, 2, 3], [4, 5, 6]) # 기본 설정값의 Figure 객체가 만들어진 후, 내부적으로.plot() Axes 호출
plt.title('Hello Plot') # Axes.set_title() 호출
plt.show() # Figure.show() 호출
plt.figure(facecolor='red', figsize=(10, 4)) # Figure 객체에 색깔과 크기까지 설정정
plt.plot([1, 2, 3], [4, 5, 6])
plt.title('Hello Plot')
plt.show()
fig = plt.figure() # Figure 객체 생성
<Figure size 432x288 with 0 Axes>
ax = plt.axes() # Axes 객체 생성
ax.hist(np.random.randn(100))
(array([ 5., 2., 5., 7., 17., 24., 16., 11., 9., 4.]),
array([-2.36681532, -1.93192652, -1.49703772, -1.06214893, -0.62726013,
-0.19237134, 0.24251746, 0.67740625, 1.11229505, 1.54718384,
1.98207264]),
<BarContainer object of 10 artists>)
ax = plt.axes()
ax.scatter(np.arange(10), np.arange(10))
<matplotlib.collections.PathCollection at 0x7f1341c53af0>
# Figure와 Axes를 함께 가져옴(기본적으로 한개의 Axes를 설정)
fig, axes = plt.subplots()
print(type(fig), type(axes))
<class 'matplotlib.figure.Figure'> <class 'matplotlib.axes._subplots.AxesSubplot'>
# Figure의 사이즈 설정, Axes의 개수 설정
fig, axes = plt.subplots(nrows=2, ncols=5, figsize=(12, 4)) # 정해진 figsize 안에 nrows, ncols 만큼의 axes를 생성
plot() 함수안에 올 수 있는 데이터
# list
plt.plot([1, 2, 3], [4, 5, 6])
plt.show()
# ndarray
plt.plot(np.array([1, 2, 3]), np.array([4, 5, 6]))
plt.show()
# Series
plt.plot(pd.Series([1, 2, 3]), pd.Series([4, 5, 6]))
plt.show()
# DataFrame
df = pd.DataFrame(np.random.randn(10, 4).cumsum(0),
columns=['A', 'B', 'C', 'D'],
index=np.arange(0, 100, 10))
df
A | B | C | D | |
---|---|---|---|---|
0 | 0.213829 | 0.158209 | 1.234090 | 1.625117 |
10 | 1.548749 | -0.829001 | -0.414488 | 3.959293 |
20 | 2.613033 | -1.590840 | -1.829204 | 4.968986 |
30 | 3.831927 | 0.818843 | -1.572401 | 3.499105 |
40 | 5.238877 | 0.061736 | -3.180235 | 2.124488 |
50 | 4.495027 | 0.665889 | -4.014447 | 1.158320 |
60 | 5.204724 | 1.713093 | -4.521490 | 1.648307 |
70 | 4.708933 | 1.292645 | -4.284156 | 1.124667 |
80 | 5.261158 | 1.270810 | -4.213980 | -0.805378 |
90 | 4.532295 | 2.175720 | -5.124437 | -0.357466 |
plt.plot(df) # df의 index가 x축, column 아래 값들이 y축으로 매칭칭
plt.show()
df.plot(kind='line') # plt.plot()이 아니라 df.plot()로 호출하면 범례(컬럼명기준)까지 생성성
plt.show()
df.plot(kind='bar')
<AxesSubplot:>
색상, 마커, 선 스타일 등 변경
Image('./images/plot.png')
plt.plot([1, 2, 3], [4, 5, 6], color='green') # 색상 변경
plt.show()
plt.plot([1, 2, 3], [4, 5, 6], color='green', linestyle='dashed') # 선 스타일 변경경
plt.show()
plt.plot([1, 2, 3], [4, 5, 6], color='green', linestyle='dashed', linewidth=3, marker='o', markersize=10) # 마커 변경
plt.show()
plt.plot([1, 2, 3], [4, 5, 6], 'go--')
plt.show()
x축, y축에 축명을 텍스트로 할당
plt.plot([1, 2, 3], [4, 5, 6], color='green', linestyle='dashed', linewidth=3, marker='o', markersize=10)
plt.xlabel('x axis', size=20)
plt.ylabel('y axis', size=20)
plt.show()
x축, y축 틱값 표기
plt.plot([1, 2, 3], [4, 5, 6], color='green', linestyle='dashed', linewidth=3, marker='o', markersize=10)
plt.xlabel('x axis', size=20)
plt.ylabel('y axis', size=20)
plt.xticks([1, 2, 3], rotation=30) # x축 눈금, 30도 회전
plt.yticks([4, 5, 6]) # y축 눈금금
plt.show()
x축, y축값 제한
plt.plot([1, 2, 3], [4, 5, 6], color='green', linestyle='dashed', linewidth=3, marker='o', markersize=10)
plt.xlabel('x axis', size=20)
plt.ylabel('y axis', size=20)
plt.xticks([0, 1, 2], rotation=30) # x축 눈금, 30도 회전
plt.yticks([3, 4, 5]) # y축 눈금
plt.xlim(0, 2)
plt.ylim(3, 5)
plt.show()
범례 설정하기
plt.plot([1, 2, 3], [4, 5, 6], label='test', color='green', linestyle='dashed', linewidth=3, marker='o', markersize=10)
plt.xlabel('x axis', size=20)
plt.ylabel('y axis', size=20)
plt.xticks([0, 1, 2], rotation=30) # x축 눈금, 30도 회전
plt.yticks([3, 4, 5]) # y축 눈금
plt.xlim(0, 2)
plt.ylim(3, 5)
plt.legend() # 범례 설정
plt.show()
여러개의 plot을 하나의 axes에서 그리기
x1 = np.arange(100)
y1 = x1 * 2
x2 = np.arange(100)
y2 = x1 * 3
plt.plot(x1, y1, label='y=2x')
plt.plot(x2, y2, label='y=3x')
plt.legend()
plt.show()
Axes 객체에서 직접 작업하기
x1 = np.arange(10)
y1 = x1 * 2
fig = plt.figure()
axes = plt.axes()
axes.plot(x1, y1, color='red', marker='+', label='line') # 선그래프
axes.bar(x1, y1, color='green', label='bar') # 막대그래프
axes.set_xlabel('x axis', size=20)
axes.set_ylabel('y axis', size=20)
axes.set_xticks(x1)
axes.legend()
plt.show()
실습
from IPython.display import Image
Image('./images/axes.png')
- 위의 그래프와 같이 여러개의 subplot을 한 figure 안에 생성하고 개별 그래프 시각화
# todo
x1 = np.arange(1, 10)
y1 = x1 * 2
x2 = np.arange(1, 20)
y2 = x2 * 2
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 8))
# 좌상단
axes[0][0].plot(x1, y1, color='red', marker='o', linestyle='dashed', label='red line')
axes[0][0].legend()
axes[0][0].set_xlabel('axes[0][0] x axis')
axes[0][0].set_ylabel('axes[0][0] y axis')
# 우상단
axes[0][1].bar(x2, y2, color='green', label='green bar')
axes[0][1].legend()
axes[0][1].set_xlabel('axes[0][1] x axis')
axes[0][1].set_ylabel('axes[0][1] y axis')
# 좌하단
axes[1][0].plot(x1, y1, color='green', marker='o', linestyle='dashed', label='green line')
axes[1][0].legend()
axes[1][0].set_xlabel('axes[1][0] x axis')
axes[1][0].set_ylabel('axes[1][0] y axis')
# 우하단
axes[1][1].bar(x2, y2, color='red', label='red bar')
axes[1][1].legend()
axes[1][1].set_xlabel('axes[1][1] x axis')
axes[1][1].set_ylabel('axes[1][1] y axis')
plt.show()
Workshop
df = pd.read_csv('./examples/서울경기이동.csv')
sr = pd.Series(df['경기도'])
sr.index = df['Unnamed: 0'].values
- 선 그래프 그리기
from IPython.display import Image
Image('./images/1.png')
# todo
plt.plot(sr.index, sr.values)
plt.show()
- 차트 제목 추가
Image('./images/2.png')
# 코랩에서 한글 안보이는 현상
# !sudo apt-get install -y fonts-nanum
# !sudo fc-cache -fv
# !rm ~/.cache/matplotlib -rf
# 폰트 설치후 커널 재시작
# plt.rc('font', family='NanumBarunGothic')
# todo
plt.rc('font', family='Malgun Gothic') # for Windows
plt.plot(sr.index, sr.values)
plt.title('서울 -> 경기 인구 이동')
plt.show()
- 축이름 추가
Image('./images/3.png')
# todo
plt.plot(sr.index, sr.values)
plt.title('서울 -> 경기 인구 이동') # 제목
plt.xlabel('기간간') # x축 이름
plt.ylabel('이동 인구수수') # y축 이름
plt.show()
- Figure 사이즈 지정(가로 14, 세로 5)
Image('./images/4.png')
# todo
plt.figure(figsize=(14, 5))
plt.plot(sr.index, sr.values)
plt.title('서울 -> 경기 인구 이동') # 제목
plt.xlabel('기간') # x축 이름
plt.ylabel('이동 인구수') # y축 이름
plt.show()
- x축 눈금 라벨 회전하기 (90도)
Image('./images/5.png')
# todo
plt.figure(figsize=(14, 5))
plt.plot(sr.index, sr.values)
plt.title('서울 -> 경기 인구 이동') # 제목
plt.xlabel('기간') # x축 이름
plt.ylabel('이동 인구수수') # y축 이름
plt.xticks(rotation=90)
plt.show()
- 마커 표시 추가
Image('./images/6.png')
# todo
plt.figure(figsize=(14, 5))
plt.plot(sr.index, sr.values, marker='o', markersize=10)
plt.title('서울 -> 경기 인구 이동') # 제목
plt.xlabel('기간') # x축 이름
plt.ylabel('이동 인구수수') # y축 이름
plt.xticks(sr.index, rotation=90)
plt.show()
- 범례 표시
Image('./images/7.png')
# todo
plt.figure(figsize=(14, 5))
plt.plot(sr.index, sr.values, marker='o', markersize=10)
plt.title('서울 -> 경기 인구 이동') # 제목
plt.xlabel('기간') # x축 이름
plt.ylabel('이동 인구수수') # y축 이름
plt.xticks(sr.index, rotation=90)
plt.legend(labels=['서울->경기'], loc='best', fontsize=15)
plt.show()
- y축 범위 지정 (최소값, 최대값) : (5000, 800000)
Image('./images/8.png')
# todo
plt.figure(figsize=(14, 5))
plt.plot(sr.index, sr.values, marker='o', markersize=10)
plt.title('서울 -> 경기 인구 이동') # 제목
plt.xlabel('기간') # x축 이름
plt.ylabel('이동 인구수수') # y축 이름
plt.xticks(sr.index, rotation=90)
plt.ylim(50000, 800000)
plt.legend(labels=['서울->경기'], loc='best', fontsize=15)
plt.show()
- 스타일 서식 지정
Image('./images/9.png')
# 스타일 리스트 출력
print(plt.style.available)
['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']
# todo
plt.style.use('ggplot')
plt.figure(figsize=(14, 5))
plt.plot(sr.index, sr.values, marker='o', markersize=10)
plt.title('서울 -> 경기 인구 이동') # 제목
plt.xlabel('기간') # x축 이름
plt.ylabel('이동 인구수수') # y축 이름
plt.xticks(sr.index, rotation=90)
plt.ylim(50000, 800000)
plt.legend(labels=['서울->경기'], loc='best', fontsize=15)
plt.show()
- 주석표시
Image('./images/10.png')
# todo
plt.style.use('ggplot')
plt.figure(figsize=(14, 5))
plt.plot(sr.index, sr.values, marker='o', markersize=10)
plt.title('서울 -> 경기 인구 이동') # 제목
plt.xlabel('기간') # x축 이름
plt.ylabel('이동 인구수수') # y축 이름
plt.xticks(sr.index, rotation=90)
plt.ylim(50000, 800000)
# 주석 표시
plt.annotate('', # 표시될 텍스트
xy = (1995, 640000), # 화살표의 머리(뾰족한 부분분)
xytext= (1970, 290000), # 화살표의 끝점
arrowprops= dict(arrowstyle='->', color='skyblue', lw=5) # 화살표 서식
)
plt.annotate('', # 표시될 텍스트
xy = (2016, 450000), # 화살표의 머리
xytext= (1996, 640000), # 화살표의 끝점
arrowprops= dict(arrowstyle='->', color='olive', lw=5) # 화살표 서식
)
plt.annotate('인구이동 증가(1970-1995)', # 표시될 텍스트
xy = (1975, 450000), # 텍스트 위치 기준점
rotation = 18,
fontsize= 15
)
plt.annotate('인구이동 감소(1995-2017)', # 표시될 텍스트
xy = (2002, 550000), # 텍스트 위치 기준점
rotation = -11,
fontsize= 15
)
plt.legend(labels=['서울->경기'], loc='best', fontsize=15)
plt.show()
댓글남기기