logo

파이썬 matplotlib에서 복잡한 레이아웃의 서브플랏 그리는 방법 📂프로그래밍

파이썬 matplotlib에서 복잡한 레이아웃의 서브플랏 그리는 방법

개요

기본적으로 plt.subplot(nrows, ncols, index)이나 plt.subplots(nrows, ncols)로 격자 형태의 서브플랏을 그릴 수 있다. 본 글에서는 조금 더 복잡한 형태의 서브플랏을 그리는 방법을 소개한다. 격자에 의존하지 않고 겹쳐그리거나 진짜 내 마음대로 그리는 방법은 여기을 참고하라.

코드

plt.subplot(nrows, ncols, index)

plt.subplot을 쓰는데, index자리에 정수가 아니라 tuple을 넣으면 여러 격자에 걸쳐서 그림을 그릴 수 있다. 개열받는 점은 여기서 index가 인덱싱도 슬라이싱도 아니라는 점이다. 따라서 (파이썬 인덱싱이 아니므로) 인덱스는 $0$이 아닌 $1$부터 시작한다. 또한 슬라이싱이 아니라 튜플이기 때문에 (3,4)는 정직하게 세번째부터 네번째까지의 subplot을 의미한다. 예시로 세 장의 그림을 윗줄에는 2장, 아랫줄에는 1장으로 배치하는 코드는 아래와 같다.

import matplotlib.pyplot as plt
import numpy as np

plt.subplot(2, 2, 1)                                     # 좌상단에 막대그래프 그리기
plt.bar(np.arange(10), np.random.randn(10))

plt.subplot(2, 2, 2)                                     # 우상단에 산점도 그리기
plt.scatter(np.random.randn(10), np.random.randn(10))

plt.subplot(2, 2, (3,4))                                 # 하단에 선그래프 그리기
plt.plot(np.random.randn(10))                           

plt.show()

gridspec

gridspec를 쓰면 위와는 달리 실제로 인덱싱과 슬라이싱을 사용할 수 있기 때문에 좀 더 편하며, 다른 코드들과도 직관적으로 잘 어울리게 코딩할 수 있다. 위와 정확히 같은 그림을 그리는 코드는,

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np

gs = gridspec.GridSpec(2, 2)                             # 그리드스펙 생성

plt.subplot(gs[0])                                       # 좌상단에 막대그래프 그리기
plt.bar(np.arange(10), np.random.randn(10))

plt.subplot(gs[1])                                       # 우상단에 산점도 그리기
plt.scatter(np.random.randn(10), np.random.randn(10))    

plt.subplot(gs[2:])                                      # 하단에 선그래프 그리기
plt.plot(np.random.randn(10))

plt.show()

레시피

가로 비율 조절

gs = gridspec.GridSpec(2, 2, width_ratios=[1,3])         # 그리드스펙 생성, 가로 비율 1:3

plt.subplot(gs[0])                                       # 좌상단에 막대그래프 그리기
plt.bar(np.arange(10), np.random.randn(10))

plt.subplot(gs[1])                                       # 우상단에 산점도 그리기
plt.scatter(np.random.randn(10), np.random.randn(10))    

plt.subplot(gs[2:])                                      # 하단에 선그래프 그리기
plt.plot(np.random.randn(10))


세로 비율 조절

gs = gridspec.GridSpec(2, 2, height_ratios=[1,2])        # 그리드스펙 생성, 세로 비율 1:2

plt.subplot(gs[0])                                       # 좌상단에 막대그래프 그리기
plt.bar(np.arange(10), np.random.randn(10))

plt.subplot(gs[1])                                       # 우상단에 산점도 그리기
plt.scatter(np.random.randn(10), np.random.randn(10))    

plt.subplot(gs[2:])                                      # 하단에 선그래프 그리기
plt.plot(np.random.randn(10))


$_{\thinspace \thinspace \square}^{\square \square}$ 꼴의 레이아웃

gs = gridspec.GridSpec(2, 4)                             # 그리드스펙 생성

plt.subplot(gs[0:2])                                     # 좌상단에 막대그래프 그리기
plt.bar(np.arange(10), np.random.randn(10))

plt.subplot(gs[2:4])                                     # 우상단에 산점도 그리기
plt.scatter(np.random.randn(10), np.random.randn(10))        

plt.subplot(gs[5:7])                                     # 하단에 선그래프 그리기
plt.plot(np.random.randn(10))

plt.subplots_adjust(wspace=1)


환경

  • OS: Windows11
  • Version: Python 3.9.13, matplotlib==3.6.2, numpy==1.23.5