시각화는 데이터를 파악하는데 매우 중요한 도구이다. 파이썬은 라이브러리(Pandas, Matplotlib, Seaborn 등)을 이용해 여러가지 그래프를 그려 데이터를 시각화 할 수 있다.
이를 통해 데이터셋을 직접 시각화해보며 데이터 분석에 필요한 탐색적 데이터 분석(EDA)을 하고 인사이트를 도출해 보자.
우선 matplotlib를 사용해 막대 그래프 그려보자
현실에서 그래프를 그리는 방법은 종이에 사각형을 그리고 x,y축을 그리고 그 안에 데이트를 입력한다. 파이썬으로 그래프를 그리는 방법도 실제로 그릴 때와 비슷하다.
아래는 간단한 막대그래프를 그리는 전체 코드
import matplotlib.pyplot as plt
%matplotlib inline
# 그래프 데이터
subject = ['English', 'Math', 'Korean', 'Science', 'Computer']
points = [40, 90, 50, 60, 100]
# 축 그리기
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
# 그래프 그리기
ax1.bar(subject, points)
# 라벨, 타이틀 달기
plt.xlabel('Subject')
plt.ylabel('Points')
plt.title("Someone's Test Result")
# 보여주기
plt.savefig('./barplot.png') # 그래프 이미지로 출력
plt.show() # 그래프 화면으로 출력
이제 하나씩 살펴보도록 한다.
첫번째로 모듈을 import하고 그래프로 그릴 데이터들을 정리해 준다.
import matplotlib.pyplot as plt
%matplotlib inline
# 그래프 데이터
subject = ['English', 'Math', 'Korean', Science', 'Computer']
points = [40, 90, 50, 60, 100]
%matplotlib inline
은 IPython에서 사용하는 매직 메서드로, Rich output
에 대한 표현방식이다. Rich output
란 그래프와 같은 그림, 소리, 애니메이션과 같은 결과물을 말한다.
IPython과 비슷한 환경인 Jupyter Notebook에서 이 명령어를 입력하면 그래프가 바로 출력된다.
참고 : IPython의 다른 매직 메서드들에 대한 더 자세한 정보 IPython 매직 명령어 정리
그래프를 그리는 순서는 하나의 그림(figure) 객체를 만들고 그 안에 하위 그래프(subplot)를 추가한다. 도화지에 축을 그리는 과정
fig = plt.figure() # 도화지(그래프) 객체 생성
ax1 = fig.add_subplot(1,1,1) # figure() 객체에 add_subplot 메서드를 이용해 축을 그려준다.
figure() 객체는 도화지(그래프) 객체이다. 객체 안에 figure(figsize=(x,y))
와 같이figsize
인자 값을 주어 그래프의 크기를 정할 수 있다.
만약 ax1 없이 fig만 작성한다면
fig = plt.figure()
출력
<Figure size 432x288 with 0 Axes>
축이 없어 그려지는 것은 없지만 figure 객체가 생성됐다고 나온다.
참고
대개 라이브러리마다 공식 API 문서가 있다. API 문서에는 라이브러리를 사용하는 사람들이 참고해야 할 사항들이 자세하게 적성되어 있다.
공식 API 문서를 읽어보는 것은 프로그래밍에서 필수적이다. 꼭 시간을 들여서 한번씩 살펴보는 것을 권한다.
지금 사용하는 matplotlib의 공식문서의 경우 matplotlib.org에 있다.
fig = plt.figure(figsize=(5,2))
ax1 = fig.add_subplot(1,1,1)
도화지 안에는 축을 여러 개 그릴 수 있다. 이는 그래프를 여러 개 그릴 수 있다는 뜻이다.
이는 add_subplot
을 통해 조정할 수 있다.
add_subplot(nrows, ncols, index)
함수 내부의 인자에 대한 설명세 개의 정수(nrows, ncols, index). 서브플롯은 nrows 행과 ncols 열이 있는 그리드에서 인덱스 위치를 취합니다. 인덱스는 왼쪽 상단 모서리에서 1에서 시작하여 오른쪽으로 증가합니다.
말로는 이해가 안된다 직접 코드를 입력하고 결과값을 보면서 이해해보자
fig = plt.figure()
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,4)
아래 그림과 같은 결과 값이 나온다. 2,2는 2행 2열로 총 4개의 그래프를 그릴 수 있다는 뜻이고 마지막 index 인자로 위치를 지정해준다.
bar()
메서드를 이용해 막대그래프를 그린다. 그리고 인자에 위에서 정의한 데이터들을 x,y 순으로 입력해준다.
# 그래프 데이터
subject = ['English', 'Math', 'Korean', 'Science', 'Computer']
points = [40, 90, 50, 60, 100]
# 축 그리기
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
# 그래프 그리기
ax1.bar(subject, points)
label, title
x라벨, y라벨, 제목을 추가하기 위해서 xlabel()
메서드와 ylabel()
메서드 title()
메서드를 이용한다.
plt.xlabel('Subject')
plt.ylabel('Points')
plt.title("Someone's Test Result")
이번에는 matplotlib를 이용해 선(line) 그래프를 그려본다.
우선 모듈을 import하고 그래프로 그릴 데이터를 정의해 준다. 이번에 사용할 데이터는 과거 아마존 주가 데이터이다.
AMZN.csv
https://finance.yahoo.com/quote/AMZN/history?p=AMZN
이번엔 주석(annotation) 등 좀 더 고급 기법을 활용하여 그래프를 그려보자
from datetime import datetime
import pandas as pd
import os
# 그래프 데이터
csv_path = "AMZN.csv"
data = pd.read_csv(csv_path, index_col=0, parse_dates=True)
price = data['Close']
# 축 그리기 및 좌표축 설정
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
price.plot(ax=ax, style='black')
plt.ylim([1600, 2200])
plt.xlim(['2019-05-01', '2020-03-01'])
# 주석달기
important_data = [(datetime(2019, 6, 3), "Low Price"), (datetime(2020, 2, 19), "Peak Price")]
for d, label in important_data:
ax.annotate(label, xy=(d, price.asof(d)+10), # 주석 달 좌표(x,y)
xytext=(d,price.asof(d)+100), # 주석 텍스트가 위치할 좌표(x,y)
arrowprops=dict(facecolor='red')) # 화살표 추가 및 색 설정
# 그리드, 타이틀 달기
plt.grid()
ax.set_title('StockPrice')
# 보여주기
plt.show()
pandas의 Series는 선 그래프를 그리기에 최적의 자료구조를 갖추고 있다. 위 예시 코드에서 price = data['Close']
가 바로 pandas의 Series이다.
뒤에 설명하겠지만, Pandas도 자체적인 선 그래프 그리기 기능을 제공한다. price.plot(ax=ax, style='black')
에서 pandas의 plot을 사용하면서, matplotlib에서 정의한 subplot 공간 ax
를 사용한 것을 볼 수 있다.
plt.xlim()
, plt.ylim()
을 통해 x,y 좌표축의 적당한 범위를 설정해 줄 수 있다.
그래프 안에 추가적으로 글자나 화살표 등 주석을 그릴 때는 annotate()
메서드를 이용한다.
주석달기는 그래프 그리기의 고급 기법이다.
grid()
메서드를 이용하면 그리드(격자눈금)를 추가할 수 있다.
위에서 figure()
객체를 생성하고 add_subplot()
으로 서브플롯을 생성하며 plot을 그린다고 했었는데, 이 2가지 과정을 생략할 수 있다. plt.plot()
명령으로 그래프를 그리면 matplotlib는 가장 최근의 figure 객체와 그 서브플롯을 그린다. 만약, 서브플롯이 없으면 서브플롯 하나를 생성한다.
plt.plot()
의 인자로 x데이터, y데이터, 마커 옵션, 색상 등의 인자를 이용할 수 있고,
import numpy as np
x = np.linspace(0, 10, 100) # 0에서 10까지 균등한 간격으로 100개의 숫자를 만들라는 뜻
plt.plot(x, np.sin(x), 'o')
plt.plot(x, np.cos(x), '--', color='black')
plt.show()
또 서브플롯도 plt.subplot
을 이용해 추가할 수 있다.
x = np.linspace(0, 10, 100)
plt.subplot(2,1,1)
plt.plot(x, np.sin(x), 'orange', 'o')
plt.subplot(2,1,2)
plt.plot(x, np.cos(x), 'orange')
plt.show()
라인 스타일은 plot()의 인자로 들어가는데 아래와 같이 다양한 방법으로 표기할 수 있다.
x = np.linspace(0,10,100)
plt.plot(x, x+0, linestyle='solid')
plt.plot(x, x+1, linestyle='dashed')
plt.plot(x, x+2, linestyle='dashdot')
plt.plot(x, x+3, linestyel='dotted')
plt.plot(x, x+0, '-g') # solid green
plt.plot(x, x+1, '--c') # dashed cyan
plt.plot(x, x+2, '-.k') # dashdot black
plt.plot(x, x+3, ':r'); # dotted red
plt.plot(x, x+4, linestyle='-') # solid
plt.plot(x, x+5, linestyle='--') # dashed
plt.plot(x, x+6, linestyle='-.') # dashdot
plt.plot(x, x+7, linestyle=':'); # dotted
pandas도 plot()
메서드를 통해 여러 가지 그래프를 그릴 수 있다.
matplotlib와 연계해 사용하면 좋다.
아래는 메서드의 각 기능을 정리해보았다
pandas.plot 메서드 인자
pandas의 data가 DataFrame 일 때, plot 메서드 인자
예제로 막대그래프 그려보기
막대그래프의 경우, kind에 bar
옵션을 주어 그릴 수 있다.
fig, axes = plt.subplots(2,1)
data = pd.Series(np.random.rand(5), index=list('abcde'))
data.plot(kind='bar', ax=axes[0], color='blue', alpha=1)
data.plot(kind='barh', ax=axes[1], color='red', alpha=0.3)
선 그래프도 그리는 방법은 비슷하다.
df = pd.DataFrame(np.random.rand(6,4), columns=pd.Index(['A', 'B', 'C', 'D']))
df.plot(kind='line')
fig = plt.figure()
figure 객체를 선언해 도화지를 펼친다.ax1 = fig.add_subplot(1,1,1)
축을 그린다.ax1.bar(x,y)
축 안에 어떤 그래프를 그릴지 메서드를 선책하고, 인자로 데이터를 넣어준다.grid
, xlabel
, ylabel
을 이용해서 추가해 준다.plt.savefig
메서드를 이용해 저장해준다.꽤 직관적으로 실제 종이와 펜으로 그래프를 그리는 순서랑 비슷한 것을 알 수 있다.
파이썬 기반의 시각화 라이브러리인 Pandas, Matplotlib, Seaborn 모두 이런 식으로 그래프를 그린다.
아래 그림은 각 그래프의 요소별 명칭으로 익혀두는 것이 좋다.