logo

Drawing Subplots with Complex Layouts in Python matplotlib 📂Programing

Drawing Subplots with Complex Layouts in Python matplotlib

Overview

Essentially, grids of subplots can be drawn using plt.subplot(nrows, ncols, index) or plt.subplots(nrows, ncols). This article introduces methods to draw more complex subplot arrangements. For methods on overlaying or truly drawing as one pleases, independent of a grid, see here.

Code

plt.subplot(nrows, ncols, index)

Using plt.subplot, placing a tuple instead of an integer in the index position allows for spanning the drawing over multiple grids. The frustrating part here is that index is neither indexing nor slicing. Thus, the index starts from $1$, not from $0$ (since it’s not Python indexing). Additionally, since it’s not slicing but a tuple, (3,4) honestly means the subplot from the third to the fourth. An example code arranging three figures, two on the top row and one on the bottom row, is as follows.

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

Using gridspec allows for actual indexing and slicing, making it more convenient and intuitively compatible with other codes. Code that draws exactly the same figure as above is,

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()

Recipes

Adjusting Horizontal Ratio

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))


Adjusting Vertical Ratio

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))


Layout in the Form of $_{\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)


Environment

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