IT/언어

[python] matplotlib의 figure(그림)과 axes(좌표축)

개발자 두더지 2021. 9. 7. 00:46
728x90

여러 개의 그래프


 여러 개의 그래프를 그릴 경우 figure과 axes이라는 개념을 사용해야한다. figure은 그림 전체, axes는 그 내부의 좌표축이다. 그림으로 본 다면 다음과 같다.

figre-axes

 실제로 그래프를 2개 그리는 경우를 예로 살펴보자. 

  [경우1] figure을 1개 준비해서, 그 안에 axes를 2개 만드는 경우

  [경우2] figure을 2개 준비해서, 그 안에 axes를 1개씩 만드는 경우

 왼쪽이 [경우1]에 대한 그림, 오른쪽은 [경우2]에 대한 그림이다. 

 코드로 나타낸다면 다음과 같다.

# [경우1]

x = np.linspace(-3, 3, 20)
y1 = x
y2 = x ** 2
 
# figure는 1개
plt.figure(figsize=(3, 4))
 
plt.subplot(2,1,1)
plt.plot(x, y1)
 
plt.subplot(2,1,2)
plt.plot(x, y2)
 
plt.show()
# [경우2]

x = np.linspace(-3, 3, 20)
y1 = x
y2 = x ** 2
 
# 첫 번째 figure
plt.figure(figsize=(3, 2))
plt.plot(x, y1)
 
# 두 번째 figure
plt.figure(figsize=(3, 2))
plt.plot(x, y2)
 
 
plt.show()

 figure 메소드로 figure을 작성하고, subplot 메소드로 axes를 만들고 있다.

 출력하면 다음과 같다.

[경우1]의 출력 결과
[경우2]의 출력 결과

파일을 저장할 때에는 figure단위로

 출력 결과를 파일로 저장할 때에는 savefig메소드를 사용한다.

plt.savefig("image.png")

 figure 단위로 저장되므로, 두 개의 그래프를 하나의 파일로 저장하고 싶다면 전자, 그렇지 않다면 후자의 방법으로 출력하여 저장하도록 하자.

 

 

subplot


그리드(grid)상에 그래프를 배치

 그리드상에 일정한 규칙으로 그래프를 배치하고 싶은 경우에는 subplot메소드를 사용한다.

subplot(행의 수, 열의 수, 플롯 번호)

 행의 수 x 열의 수로 형성된 그리드에 figure가 분할되어. 플롯 번호의 위치에 좌표축이 만들어진다.

 플롯 번호는 윈쪽 위가 1로 오른쪽 방향, 아래 방향으로 감에 따라 값이 커진다. 예를 들어 2x2의 그리드의 경우는 아래와 같이 된다.

1 2
3 4
x = np.linspace(-3, 3, 20)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4
 
plt.figure(figsize=(6,4))
 
# 왼쪽 위
plt.subplot(2,2,1)
plt.plot(x, y1)
 
# 오른쪽 위
plt.subplot(2,2,2)
plt.plot(x, y2)
 
# 왼쪽 아래
plt.subplot(2,2,3)
plt.plot(x, y3)
 
# 오른쪽 아래
plt.subplot(2,2,4)
plt.plot(x, y4)
 
plt.show()

plt.subplot(2, 2, 1)는 컴마를 생략해 plt.subplot(221) 와 같이 쓸 수 있다. 코드의 결과는 다음과 같다.

다른 작성방법

위의 샘플 코드는 아래의 두 가지 방법으로 바꿔서 작성할 수 있으며, 결과는 동일하다.

좌표를 먼저 확보하는 방법

x = np.linspace(-3, 3, 20)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4
 
fig, axs = plt.subplots(2, 2, figsize=(6, 4))
 
# 왼쪽 위
axs[0, 0].plot(x, y1)
 
# 오른쪽 위
axs[0, 1].plot(x, y2)
 
# 왼쪽 아래
axs[1, 0].plot(x, y3)
 
# 오른쪽 아래
axs[1, 1].plot(x, y4)
 
plt.show()

figure에 add_subplot

x = np.linspace(-3, 3, 20)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4
 
fig = plt.figure(figsize=(6, 4))
 
# 왼쪽 위
ax1 = fig.add_subplot(2, 2, 1)
ax1.plot(x, y1)
 
# 오른쪽 위
ax2 = fig.add_subplot(2, 2, 2)
ax2.plot(x, y2)
 
# 왼쪽 아래
ax3 = fig.add_subplot(2, 2, 3)
ax3.plot(x, y3)
 
# 오른쪽 아래
ax4 = fig.add_subplot(2, 2, 4)
ax4.plot(x, y4)
 
plt.show()

 

 

axes


자유롭게 그래프를 배치

 자유롭게 그래프를 배치하고 싶은 경우 axes 메소드를 사용한다.

axes([왼쪽, 아래, 폭, 높이])

 각 값은 0부터 1사이의 소수만 지정할 수 있다.

x = np.linspace(-3, 3, 20)
y1 = x
y2 = x ** 2
 
fig = plt.figure(figsize=(6, 4))
 
plt.axes([0.1, 0.1, 0.8, 0.8])
plt.plot(x, y1)
 
plt.axes([0.6, 0.2, 0.25, 0.3])
plt.plot(x, y2)
 
plt.show()

 출력 결과는 다음과 같다.

 

 

 

gridspec


그리드 상에 불규칙적으로 배치

 GridSpec를 사용하면, 그리드 상에 불규칙적으로 그래프를 배치할 수 있다.

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
 
x = np.linspace(-3, 3, 20)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4
 
plt.figure(figsize=(6, 4))
gs = gridspec.GridSpec(2,3)
 
plt.subplot(gs[0, :2])
plt.plot(x, y1)
plt.text(-2, 1.5, 'gs[0, :2]', size=15)
 
plt.subplot(gs[:, -1])
plt.plot(x, y2)
plt.text(-2, 8, 'gs[:, -1]', size=15)
 
plt.subplot(gs[1, 0])
plt.plot(x, y3)
plt.text(-2, 17, 'gs[1, 0]', size=15)
 
plt.subplot(gs[1, 1])
plt.plot(x, y4)
plt.text(-2, 70, 'gs[1, 1]', size=15)
 
plt.show()

포인트

아래의 코드로 figure을 2x3의 그리드로 분할한다.

gs = gridspec.GridSpec(2,3)

gs를 2x3의 2차원 배열로 가정해, 그래프를 배치하고 싶은 장소에 지정할 수 있다. 예를 들어,

gs[0, 0]  ⇒ 왼쪽 위
gs[0, :]  ⇒ 1행의 모두
gs[:, -1] ⇒ 마지막 열 모두

이 gs[x, x]를 subplot에 전달해 좌표축을 만든다.

plt.subplot(gs[:, -1])

그럼 출력 결과는 다음과 같다.


참고자료

http://ailaby.com/matplotlib_fig/

728x90