컴퓨터/프로그래밍

[Python] 파이썬 기초 12: Matplotlib

옆동네애옹이 2024. 9. 6. 11:34
728x90

Matplotlib

  • python, numpy를 위한 plotting library
  • 사용법
  1. 범용 GUI toolkits를 사용하는 applications에 내장가능한 객체지향 API
  2. Matlab과 매우 닮은 절차적 Pylab interface: 여태 이 방법으로 사용

Matplotlib.pyplot

  • matplotlib가 MATLAB처럼 작동하도록 하는 명령 스타일 함수들의 모음
  • 한 문장 명령 추가할 때마다 figure에 변화 발생
    • figure: 그래프 그리는 데 필요한 모든 요소들을 포함하는 최상위 container
    • state 기반 API

Line Plot

matplot.pyplot.plot()

  • 2차원 평면 그래프에서 다음 점들을 선분으로 연결해 그래프를 그리는 함수

$P0(x0, y0), P1(x1, y1), ..., Pn-1(xn-1, yn-1)$

plot([x0, x1, ..., x_{n-1}], [y0, y1, ... , y_{n-1})

  • sequence형 data 2개를 argument로 전달

ex) 다음 네 점을 연결하는 그래프를 그려라

%matplotlib inline
x = [0, 1, 2, 3] # x, y 좌표를 sequence type data로 만들어
y = [1, -1, 1, -1]
plt.plot(x, y)
plt.xlabel("$x$") # xlabel에 text 추가, $ 중간에 문장 넣어
  • plot([x], y): x를 제거하고 y만 argument로
    • 하나만 들어오면 자동적으로 y로 간주하고, x는 0에서 시작하는
%matplotlib inline
x = [0, 1, 2, 3] # x, y 좌표를 sequence type data로 만들어
y = [1, -1, 1, -1]
plt.plot(y)
plt.xlabel("$x$") # xlabel에 text 추가, $ 중간에 문장 넣어
  • plot([x], y, [fmt])
    • fmt = '[marker][line][color]'
    • 선분의 format 지정 가능.
%matplotlib inline
x = [0, 1, 2, 3] # x, y 좌표를 sequence type data로 만들어
y = [1, -1, 1, -1]
plt.plot(x, y, 'go-')
# marker:green, o: 원 형태 marker, -: 실선
plt.xlabel("$x$") # xlabel에 text 추가, $ 중간에 문장 넣어

plt.plot(x, y, 'r*--')
# r: red *:별표 --:점선

plt.plot(x, y, 'y^-.')
# y: yellow ^: 삼각형 -.: 

plt.plot(x, y, 'md:')
# m: magenta, d: diamond marker, : 점선
  • pyplot line style
    • '-': solid line style
    • '—': dashed line style
    • '-.': dash-dot line style
    • ':': dotted line style
  • colors
    • 'b': blue
    • 'g': green
    • 'r': red
    • 'c': cyan
    • 'm': magenta
    • 'y': yellow
    • 'k': black
    • 'w': white

grid 표시

  • grid(True)
plt.ploy(x, y, 'kX-', markersize=10)
grid(True, axis=x, y)

여러 개의 그래프 동시에 그리기

  • plot([x], y, [fmt], [x2], y2, [fmt])
x = np.arange(0, 1, 0.01)
y = np.sin(2*np.pi*x) # sin(2pix)
y2 = np.cos(2*np.pi*x) # cos(2pix)
plt.plot(x, y, x, y2)
# line 색, style 변경도 가능.

matplot.pyplot.xlim(), ylim()

  • xlim((left, right))
  • ylim((bottom, top))

matplot.pyplot.xticks(), yticks()

  • 가로세로축에 숫자, 문자 표시하며 순자, 문자 위치를 조그맣게 표시하는 것
  • 표시하고 싶은 tick의 형태를 sequence로 만들어 argument로 지정
  • xticks()
  • yticks()
x = np.arange(0, 1, 0.01)
y = np.sin(2*np.pi*x) # sin(2pix)
y2 = np.cos(2*np.pi*x) # cos(2pix)
plt.plot(x, y, x, y2)
plt.xticks([0, 0.5, 1])
plt.yticks([-1, -0.5, 0, 0.5, 1])

xlabels = ['spring', 'summer', 'fall', 'winter']
plt.xticks(range(4), xlabels) 
# arg1 sequence와 xlab 일대일대응되어 표시됨

plt.xticks(range(4), xlabels, rotation='vertical')
# rotation: 문자의 회전방향 지정(세로방향)
plt.xticks(range(4), xlabels, rotation=45) # 음수도 가능
plt.yticks([-1, 1], ['in', 'out'], rotation=-30)

matplot.pyplot.legend()

  • 각 line에 대한 설명을 문자열로 표현(범례)
x = np.arange(0, 1, 0.01)
y = np.sin(2*np.pi*x) # sin(2pix)
y2 = np.cos(2*np.pi*x) # cos(2pix)
plt.plot(x, y, label='$sin(2\\pi x)$')
plt.plot(x, y2, label='$\\cos(2\\pi x)$')
plt.legend() # argument 지정 안하면 적당한 위치에 표현됨
  • legend()의 loc parameter(location)
    • best:0, upper right:1, upper left:2, ... center:10

matplot.pyplot.title()

x = np.arange(0, 1, 0.01)
y = np.sin(2*np.pi*x) # sin(2pix)
y2 = np.cos(2*np.pi*x) # cos(2pix)
plt.plot(x, y, label='$sin(2\\pi x)$')
plt.plot(x, y2, label='$\\cos(2\\pi x)$')
plt.legend() 
plt.title("Plots of sine and cosine", loc='right') 

그래프의 종횡비(aspect ratio) 설정

plt.gca().set_aspect(True) # gca: get current axis
t = np.linspace(np.pi/2, np.pi/2 + 4*np.pi, 6)
# 꼭지점 좌표는 원주를 5등분 한것.
x = np.cos(t)
y = np.sin(t)
plt.plot(x, y)
plt.show()
  • 가로축, 세로축 scale 정확히 일치해야 할 경우(ratio 필요한 경우)
  • plt.gca().set_aspect(True) # gca: get current axis
    • 현재 그래프들 그려져 있는 axis(figure 내 graph 구성요소) instance return. 가로세로 비율 1:1 됨

matplot.pyplot.figure()이용한 figure 크기 지정

  • plt.figure(figsize=(width, height))
    • figsize: (float, float), optional,default=None
    • width, height in inches
      • default: rcParams["figure.figsize"] = [6.4, 4.8]
plt.figure(figsize=(8,3))
# 가로길이 8, 세로길이 3인 그림 그리기
x = np.arange(0, 1, 0.01)
y = np.sin(2*np.pi*x)
y2 = np.cos(2*np.pi*x)

plt.subplot: 현재의 figure에 새로운 axes 추가

ax = plt.gca() # get the current axes 축, pipe등 모두 포함
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0)) # x축 위치 0으로 변경
# spines: boundary표시하는 4개의 boxes
# right, top가장자리 none

plt.subplot(): 현재 figure에 새로운 axes 추가

# 현재 figure 안에 여러 개 위치한다고 가정
plt.plot(x, y)
plt.subplot(2, 3, 1)
plt.plot(x, 2y)
plt.subplot(231)
# axis 마지막 숫자는 0아니고 1임. 새로운 함수 추가할 때 python을 일반적으로 0인데 여기선 1

plt.plt.suptitle(): figure의 title

plt.suptitle("") # 전체제목

# 3개가 한세트! subplot 기준으로
plt.subplot(231)
plt.plot(x, y1)
plt.title("")

plt.tight_layout() # 적당한 간격 확보 가능

plt.scatter()

  • 산포도 그리기
    • 산포도: 서로 다른 두 변수 값을 이차원 평면에서 점으로 표현
x = [0, 1, 2, 3]
y = [1, -1, 1, -1]
plt.scatter(x, y, marker='D') # marker 표현 가능
plt.show()
  • 두 변수 사이 상관관계 파악 쉬움
np.corrcoef(x, y) # pearson 상관계수: correlation coeffecient
# 마찬가지로 1 기준 대각선으로 나타남

plt.pie(): Pie plot 그리기

import csv

populations = {}
with open('populations.csv', mode='r', encoding='utf8') as csvfile:
	csvfile = csv.reader(csvfile)
	for line in csvfile:
		name, num = line.split(':')
		populations[name] = int(num) 
populations # dictionary
plt.rcParams["font.family"] = 'NanumGothic' # 나눔고딕

plt.figure(figsize=(8, 8))
plt.pie(populations.values(), labels=populations.keys()) 
# dict니까 value, key로 값, label 가능. sequence랑 가타
plt.show()

exp = np.zeros(len(populations))
exp[0] = 0.5
exp[8] = 0.1
plt.(, roatatelabels=True, shadow=True, explode=exp, autopct='%3.1f'))
# rotatelabels: 회전, shadow: 음영
# explode = 특정 위치에 parameter 이용: 특정 slice 돌출시키기
# [0]은 0.5만큼, [8]은 0.1만큼 돌출, autopct: 백분율 표시

Plt.bar(): 막대그래프

x = [0, 1, 2, 3]
y = [1, 3, 2, 4]
plt.bar(x, y, width=0.5, bottom=0.5, align='edge', color='cyan') 
# width: 직사각형의 폭, bottom: 막대그래프 시작 base 지정
# align: 막대그래프의 중간에 0이 아니고 젤 왼쪽에 위치
# color를 하나로통일도 되고, sequence로 만들어도 되고
# edgecolor: boundary 색 지정
# yerr=[, , , ,]: x축 위에 평균..등 선으로 표시

3차원 그래프 그리기

%matplotlib inline
from mpl_toolkits.mplot3d.axes3d import Axes30
import matplotlib
import matplotlib.pyplot as plt
a
728x90