데이터 분석

데이터 분석을 통한 세상 엿보기

그래프와 시각화

matplotlib

nova-unum 2022. 7. 14. 15:29

http://matplotlib.org

 

Matplotlib — Visualization with Python

seaborn seaborn is a high level interface for drawing statistical graphics with Matplotlib. It aims to make visualization a central part of exploring and understanding complex datasets. statistical data visualization Cartopy Cartopy is a Python package des

matplotlib.org

https://matplotlib.org/stable/gallery/index.html

 

 

Examples — Matplotlib 3.5.2 documentation

This page contains example plots. Click on any image to see the full image and source code.

matplotlib.org

 정보 시각화는 데이터분석에서 무척 중요한 일 중 하나다. 시각화는 특잇값을 찾아내거나, 데이터 변형이 필요한지 알아보거나, 모델에 대한 아이디어를 찾기 위한 과정의 일부이기도 한다. 웹상에서 구현되는 시각화가 최종 목표일 수도 있다.  파이썬은 다양한 시각화 도구를 구비하고 있다.    matplotlib과 matplotlib 기반의 도구들을 우선으로 살펴본다.


 matplotlib은 주로 2D 그래프를 위한 데스크톱 패키지로, 출판물 수준의 그래프를 만들어 내도록 설계되었다.  matplotlib 프로젝트는 파이썬에서 매트랩과 유사한 인터페이스를 지원하기 위해 2002년 존 헌터가 시작했다.

 

matplotlib은 모든 운영체제의 다양한 GUI 벡엔드를 지원하고 있으며 PDF, SVG, JPG, PNG, BMP, GIF 등 일반적으로 널리 사용되는 벡터 포맷과 래스터 포맷으로 그래프를 저정할 수 있다.  시간이 흐름에 따라 내부적으로 matplotlib을 사용하는 새로운 데이터 시각화 도구들이 생겨났는데 그 중 하나가  seaborn 라이브러리다.

 

https://matplotlib.org/stable/tutorials/introductory/usage.htl

 

Basic Usage — Matplotlib 3.5.2 documentation

Axes labels and text set_xlabel, set_ylabel, and set_title are used to add text in the indicated locations (see Text in Matplotlib Plots for more discussion). Text can also be directly added to plots using text: mu, sigma = 115, 15 x = mu + sigma * np.rand

matplotlib.org


CONTENTS

. matplotlib

. figure와 서브플롯

. 서브플롯 간의 간격 조절하기

. 색상, 마커 선 스타일

. 눈금, 라벨, 범례

. 제목, 축 이름, 눈금, 눈금 이름 설정하기

. 범례 추가하기

. 주석과 그림 추가하기

. 그래프를 파일로 저장하기

. matplotlib 설정

 


figure와 서브플롯
 matplotlib에서 그래프를 Figure 객체 내에 존재한다. 그래프를 위한 새로운 figure(피겨)는 plt.figure를 사용해서 생성할 수 있다.  plt.figure에는 다양한 옵션이 있는데 그중 figsize는 파일에 저장할 경우를 위해 만들려는 figure의 크기와 비율을 지정할 수 있다. 빈 figure로는 그래프를 그릴 수 없다. add_subplot을 사용해서 최소 하나 이상의 subplots를 생성해야 한다.

import matplotlib.pyplot as plt
fig = plt.figure()

ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)

figure가 2 X 2 크기이고 4개의 서브플롯 중에서 첫 번째를 선택하겠다는 의미이다. 다음처럼 2개의 서브플롯으르 더 추가하면 다음과 같은 모양이 된다. 

matplotlib은 가장 최근의 figure와 그 서브플롯을 그린다. 서브플롯이 없다면 서브플롯 하나를 생성한다. 

하나의 그래프를 가지는 figure

fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)

plt.plot(np.random.randn(50).cumsum(), 'k--')

'k--' 옵션은 검은 점선을 그리기 위한 스타일 옵션이다. 

 

fig.add_subplot에서 반환되는 객체는 AxesSubplot인데, 각각의 인스턴스 메서드를 호출해서 다른 빈 서브플롯에 직접 그래프를 그릴수 있다. 

fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)

plt.plot(np.random.randn(50).cumsum(), 'k--')
_ = ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)
ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))

matplotlib 문서에서 여러 가지 그래프 종류를 확인할 수 있다.

https://matplotlib.org/stable/plot_types/index

 

Plot types — Matplotlib 3.5.2 documentation

Overview of many common plotting commands in Matplotlib. Note that we have stripped all labels, but they are present by default. See the gallery for many more examples and the tutorials page for longer examples. Unstructured coordinates Sometimes we collec

matplotlib.org

 

특정한 배치에 맞추어 여러 개의 서브플롯을 포함하는 figure를 생성하는 일은 흔히 접하게 되는 업무인데 이를 위한 plt.subplots라는 편리한 메서드가 있다. 이 메서드는 Numpy 배열과 서브플롯 객체를 새로 생성하여 반환한다.

fig, axes = plt.subplots(2,3)
axes

 

axes 배열은 axes[0, 1]처럼 2차원 배열로 쉽게 색인될 수 있어서 편리하게 사용할 수 있다.  서브플롯이 같은 x축 혹은 y축은 가져야 한다면 각각 sharex와 sharey를 사용해서 지정할 수 있다. 같은 범위 내에서 데이터를 비교해야 할 경우 특히 유용하다. 그렇지 않으면 matplotlib은 각 그래프의 범위를 독립적으로 조정한다. 

 

pyplot.subplots 옵션

nrows 서브플롯의 로우 수
ncols 서브플롯의 컬럼 수
sharex 모든 서브플롯이 같은 x축 눈금을 사용하도록 한다.(xlim 값을 조절하면 모든 서브플롯에 적용된다).
sharey 모든 서브플롯이 같은 y축 눈금을 사용하도록 한다.(ylim 값을 조절하면 모든 서브플롯에 적용된다).
subplot_kw add_subplot을 사용해서 각 서브플롯을 생성할 때 사용할 키워드를 담고 있는 사전
**fig_kw figure를 생성할 때 사용할 추가적인 키워드 인자. 예를 들면 plt.subplots(2, 2, figsize=(8,6)

 

서브플롯 간의 간격 조절하기

matplotlib은 서브플롯 간에 적당한 간격 spacing과 여백 padding을 추가해준다. 이 간격은 전체 그래프의 높이와 너비에 따라 상대적으로 결정된다. 그러므로 프로그램을 이용하든 아니면 직접 GUI 원도우의 크기를 조정하든 그래프의 크기가 자동적으로 조절된다.  서브플롯 간의 간격은 Figure 객체의 subplots_adjust 메서드를 사용해서 쉽게 바꿀 수 있다. subplots_adjust 메서드는 최상위 함수로도 존재한다. 

 

subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)

 

wspace와 hspace는 서브플롯 간의 간격을 위해 각각 figure의 너비와 높이에 대한 비율을 조절한다.

 

다음 코드는 서브플롯 간의 간격을 주지 않은 그래프르르 생성하는 코드다.

fig, axes = plt.subplots(2,2, sharex=True, sharey=True)
for i in range(2) :
    for j in range(2):
        axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5)
plt.subplots_adjust(wspace=0, hspace=0)

그래프를 그렸을 때 축 이름이 겹치는 경우가 있다.  matplotlib은 그래프에서 이름이 겹치는지 검사하지 않기 때문에 이와 같은 경우에는 눈금  위치와 눈금 이름을 명시적으로 직접 지정해야 한다. 

 

색상, 마커, 선 스타일

matplotlib에서 가장 중요한 plot함수는 x와 y 좌표값이 담긴 배열과 추가적으로 색상과 선스타일을 나타내는 축약 문자열로 인자로 받는다. 

ax.plot(x, y, 'g--')

ax.plot(x, y, linestyle='--', color='g')

흔히 사용되는 색상을 위해 몇 가지 색상 문자열이 존재하지만 RGB값(예:#CECECE)을 직접 지정해서 색상표에 있는 어떤 색이라도 지정할 수 있다. 

http://www.n2n.pe.kr/lev-1/color.htm

 

256 color 색상표

6600CC R - 102 G - 000 B - 204

www.n2n.pe.kr

https://www.rapidtables.org/ko/web/color/RGB_Color.html

 

RGB 색상 코드 차트 🎨

RGB 색상 코드 차트 RGB 색상 선택기 | RGB 색상 코드 차트 | RGB 색 공간 | RGB 색상 형식 및 계산 | RGB 색상 표 RGB 색상 선택기 RGB 색상 코드 차트 색상 에 커서를 갖다 대면 아래의 16 진수 및 10 진수 색

www.rapidtables.org

 

선그래프는 특정 지점의 실제 데이터를 돋보이게 하기 위해 마커를 추가하기도 한다. matplotlib은 점들을 잇는 연속된 선그래프를 생성하기 때문에 어떤 지점에 마커를 설정해야 하는지 확실치 않은 경우가 종종 있다. 마커도 스타일 문자열에 포함시킬 수 있는데 색상 다음에 마커 스타일이 오고 그 뒤에 선 스타일을 지정한다.

\https://matplotlib.org/stable/api/markers_api.html

 

matplotlib.markers — Matplotlib 3.5.2 documentation

matplotlib.markers Functions to handle markers; used by the marker functionality of plot, scatter, and errorbar. All possible markers are defined here: marker symbol description "." point "," pixel "o" circle "v" triangle_down "^" triangle_up "<" triangle_

matplotlib.org

from numpy.random import randn
plt.plot(randn(30).cumsum(), 'ko--')

 

좀 더 명시적인 방법으로 표현하면 plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')

선 그래프를 보면 일정한 간격으로 연속된 지점이 연결되어 있다. 이 역시 drawstyle옵션을 이용해서 바꿀수 있다. 

data = np.random.randn(30).cumsum()
plt.plot(data, 'k--', label='Default')
plt.plot(data, 'k-', drawstyle='steps-post', label='steps-post')
plt.legend(loc='best')

다양한 스타일이 적용된 선그래프

 

label 인자로  plot을 전달했기 때문에 plt.legend를 이용해서 각 선그래프의 범례를 추가할 수 있다. 축에 대한 범례를 추가하려면 ax.legend를 호출하자.

 

눈금, 라벨, 범례

그래프를 꾸미는 방법은 크게 2가지가 있다.

pyplot 인터페이스를 사용해서 순차적으로 꾸민든가(즉, matplotlib.pyplot) 아니면 matplotlib이 제공하는 API를 사용해서 좀 더 객체지향적인 방법으로 꾸미는 것이다. 

pyplot 인터페이스는 대화형 사용에 맞추어 설계되었으며 xlim, xticks, xticklabels 같은 메서드로 이루어져 있다. 이런 메서드로 표의 범위를 지정하거나 눈금 위치, 눈금 이름을 조절할 수 있다. 

 . 아무런 인자 없이 호출하면 현재 설정되어 있는 매개변수의 값을 반환한다. plt.xlim 메서드는 현재 x축의 범위를 반환한다. 

. 인자를 전달하면 매개변수의 값을 설정한다 . 예를 들어 plt.xlim([0,10])을 호출하면 x축의 범위가 0부터 10까지로 설정된다. 

이 모든 메서드는 현재 활성화된 혹은 가장 최근에 생성된 AxesSubplot 객체에 대해 동작한다. 위에서 소개한 모든 메서드는 서브플롯 객체의 set/get 메서드로도 존재하는데, xlim 이라면 ax.get_xlim과 ax.set_xlim 메서드가 존재한다. 

 

제목, 축 이름, 눈금, 눈금 이름 설정하기

x축 눈금이 포함된 간단한 그래프

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(np.random.randn(1000).cumsum())

 

x축을 꾸민 간단한 그래프

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(np.random.randn(1000).cumsum())

ticks = ax.set_xticks([0, 250, 500, 750, 1000])
labels = ax.set_xticklabels(['one','two','three','four','five']
                            , rotation=30, fontsize='small')
ax.set_title('My first matplotlib plot')
ax.set_xlabel('Stages')

x축의 눈금을 변경하기 위한 가장 쉬운 방법은 set_xticks와 set_xticklabels 메서드를 사용하는 것이다. set_xticks 메서드는 전체 데이터 범위를 따라 눈금을 어디에 배치할지 지정한다. 기본적으로 이 위치에 눈금 이름이 들어간다. 하지만 다른 눈금 이름을 지정하고 싶다면 set_xticklabels를 사용하면 된다.

set_xlabel 메서드는 x축에 대한 이름을 지정하고  set_title 메서드는 서브플롯의 제목을 지정한다. 

x대신 y를 써서 같은 과정을 y축에 대해 진행할 수 있따. axes 클래스는 플롯의 속성을 설정할 수 있도록 set 메서드를 제공한다. 

props ={
    'title': 'My first matplotlib plot',
    'xlabel':'Stages'
}
ax.set(**props)

 

범례 추가하기

범례는 그래프 요소를 확인하기 위해 중요한 요소다. 범례를 추가하는 몇 가지 방법이 있는데 가장 쉬운 방법은 각 그래프에 label 인자를 넘기는 것이다.

from numpy. random import randn

fig = plt.figure() 
ax = fig.add_subplot(1, 1, 1)
ax.plot(randn(1000).cumsum(), 'k', label='one')
ax.plot(randn(1000).cumsum(), 'k--', label='two')
ax.plot(randn(1000).cumsum(), 'k', label='three')

ax.legend(loc='best') # = plt.legend

legend 메서드에는 범례 위치를 지정하기 위한 loc 인자를 제공한다. legend 메서드를 문서에서 더 자세한 정보를 확일할 수 있다. (ax.legend? 명령으로  확인해보자) loc 은 범례를 그래프에서 어디에 위치시킬지 지정해주는 인자다. 범례에서 제외하고 싶은 요소가 있다면 label 인자를 넘기지 않거나 label='_nolegend_' 옵션을 사용하면 된다.

주석과 그림 추가하기

주석과 글자는 text, arrow, annotate 함수를 이용해서 추가할 수 있다. text 함수는 그래프 내의 주어진 좌표(x, y)에 부가적인 스타일로 글자를 그려준다. 

ax.text(x, y, 'Hello world!', family = 'monospace', fontsize=10)

야후! 파이낸스에서 얻은 2007년부터의 S&P 500 지수 데이터로 그래프를 생성하고 2008-2009년 사이에 있었던 재정위기중 중요한 날짜를 주석으로 추가해보자.

2008- 2009 금융 위기 날짜를 나타낸 그래프

ax.annotate 메서드를 이용해 x, y 좌표로 지정한 위치에 라벨을 추가했으며 set_xlim과 set_ylim 메서드를 이용해서 그래프의 시작과 끝 경계를 직접 지정했다. 

https://matplotlib.org/stable/tutorials/text/annotations.html

 

Annotations — Matplotlib 3.5.2 documentation

Let's start with a simple example. text takes a bbox keyword argument, which draws a box around the text: t = ax.text( 0, 0, "Direction", ha="center", va="center", rotation=45, size=15, bbox=dict(boxstyle="rarrow,pad=0.3", fc="cyan", ec="b", lw=2)) The pat

matplotlib.org

asof 메서드는 인덱스 기준으로 where이전에 결측치가 없는 마지막 행을 구한다.

df.asof(where, subset=None) , where은 기준이 되는 인덱스 값, subset은 기준이 되는 열

 

matplotlib은 일반적인 도형을 표현하기 위한 patches 라는 객체를 제공한다. 그중 Rectangle과 Circle 같은 것은 matplotlib.pyplot에서도 찾을 수 있지만 전체 모음은 matplotlib.patches에 있다.

그래프에 도형을 추가하려면 patches 객체인 shp를 만들고 서브플롯에 ax.add_patch(shp)를 호출한다.

https://matplotlib.org/stable/api/patches_api.html

 

matplotlib.patches — Matplotlib 3.5.2 documentation

Arc(xy, width, height[, angle, theta1, theta2]) An elliptical arc, i.e. a segment of an ellipse.

matplotlib.org

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

rect = plt.Rectangle((0.2, 0.75), 0.4, 0.15, color='k', alpha=0.3)
circ = plt.Circle((0.7, 0.2), 0.15, color='b', alpha=0.3)
pgon = plt.Polygon([[0.14, 0.15], [0.35, 0.4], [0.2, 0.6]], color='g', alpha=0.5)

ax.add_patch(rect)
ax.add_patch(circ)
ax.add_patch(pgon)

 

그래프를 파일로 저정하기

활성화된 figure는 plt.savefig 메서드를 이용해서 파일로 저장할 수 있다. 이 메서드는 figure객체의 인스턴스 메서드인 savefig와 동일하다. 

figure를 SVG 포맷으로 저장하려면 다음처럼 하면 된다.

plt.savefig("figpath.svg")

파일 종류는 확장자로 결정된다. 그러므로  .svg 대신에  .pdf를 입력하면 PDF 파일을 얻게 된다. 출판용 그래픽 파일을 생성할 때 내가 자주 사용하는 몇 가지 중요한 옵션이 있는데 바로 dpi와 bbox_inches다. dpi는 인치당 도트 해상도를 조절하고 bbox_inches는 실제 figure 둘레의 공백을 잘라낸다. 그래프 간 최소 공백을 가지는 400DPI짜리 PNG 파일을 만들려면 아래와 같이 입력한다.

plt.savefig("figpath.png", dpi=400, bbox_inches='tight)

savefig 메서드는 파일에 저장할 뿐만 아니라 BytesIO처럼 파일과 유사한 객체에 저장하는 것도 가능하다.

from io import BytesIO
buffer = BytesIO()
plt.savefig(buffer)
plot_data = buffer.getvalue()

Figure.savefig 옵션

fname 파일경로나 파이썬의 파일과 유사한 객체를 나타내는 문자열. 저장되는 포맷은 파일 확장자를 통해 결정된다. 예를들어 .pdf는 PDF 포맷, .png는 PNG포맷
dpi figure의 인치당 도트 해상도, 기본값은 100이며, 설정 가능하다.
facecolor, edgecolor 서브플롯 바깥 배경 색상. 기본값은 'w' (흰색)다.
format 명시적인 파일 포맷('png', 'pdf', 'svg',' ps', 'eps', ...)
bbox_inches figure에서 저장할 부분.  만약  'tight' 를 지정하면 figure 둘레의 비어 있는 공간을 모두 제거한다. 

matplotlib 설정

matplotlib은 출판물용 그래프를 만드는데 손색이 없는 기본 설정과 색상 스키마를 함께 제공한다. 다행스럽게도 거의 모든 기본 동작은 많은 전역 인자를 통해 설정 가능한데, 그래프 크기, 서브플롯 간격, 색상, 글자 크기, 격자 스타일과 같은 것들을 설정 가능하다. matplotlib의 환경 설정 시스템은 두 가지 방법으로 다룰 수 있는데 첫 번째는 rc 메서듣를 사용해서 프로그래밍적으로 설정하는 방법이다. 예를 들어 figure의 크기를 10 X 10으로 전역 설정해두고 싶다면 다음 코드를 실행한다.

 

plt.rc('figure', figsize=(10, 10))

 

rc 메서드의 첫 번째 인자는 설정하고자 하는 'figure', 'axes', 'xtick', 'ytick', 'grid', 'legend' 및 다른 컴포넌트의 이름이다.  그다음으로 설정할 값에 대한 키워드 인자를 넘기게 된다. 이 옵션을 작성하려면 파이썬의 사전 타입을 사용한다. 

font_options = {'family':'monospace',
               'weight':'bold',
               'size':'small'}
plt.rc('font',**font_options)

더 많은 설정과 옵션의 종류는 matplotlib/mpl-data 디렉터리에 matplotlibrc라는 파일에 저장되어 있다. 만약 이 파일을 적절히 수정해서 사용자 홈 디렉터리에 .matplotlibrc라는 이름으로 저장해두면 matplotlib을 사용할 때마다 불러오게 된다.

seaborn 패키지는 내부적으로 matplotlib 설정을 사용하는 내장 테마 혹은 스마일을 제공한다.