Matplotlib subplots() 函数
subplots() 是创建 Figure 和一组 Axes 子图的推荐方式,一次调用即可完成画布和子图的创建。
它是 Matplotlib 面向对象接口的核心入口函数。
函数定义
pyplot 接口
matplotlib.pyplot.subplots(nrows=1, ncols=1, *, sharex=False,
sharey=False, squeeze=True, width_ratios=None,
height_ratios=None, subplot_kw=None, gridspec_kw=None,
**fig_kw)
Figure 方法
Figure.subplots(nrows=1, ncols=1, *, sharex=False, sharey=False,
squeeze=True, width_ratios=None, height_ratios=None,
subplot_kw=None, gridspec_kw=None)
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| nrows | int | 子图行数,默认 1 |
| ncols | int | 子图列数,默认 1 |
| sharex / sharey | bool 或 str | 是否共享 x/y 轴。可传入 'all'/'row'/'col'/'none' 或布尔值 |
| squeeze | bool | 若为 True,单行/单列时自动去除多余维度,默认 True |
| width_ratios | list | 各列宽度比例,如 [1, 2] 表示第 2 列是第 1 列的 2 倍宽 |
| height_ratios | list | 各行高度比例,如 [2, 1] 表示第 1 行是第 2 行的 2 倍高 |
| subplot_kw | dict | 传递给子图创建的参数,如 dict(projection='polar') 创建极坐标子图 |
| gridspec_kw | dict | 传递给 GridSpec 的参数,如 dict(hspace=0.3, wspace=0.3) 设置子图间距 |
| **fig_kw | dict | 传递给 Figure 创建的参数,如 figsize=(8,6), dpi=100, layout='constrained' |
subplots() 返回值是一个元组
(fig, ax)。当只有一行一列时 ax 是单个 Axes 对象,多行多列时 ax 是 Axes 的二维数组。
使用示例
示例 1:单子图
实例
import matplotlib.pyplot as plt
import numpy as np
# 创建单个子图(最常用写法)
fig, ax = plt.subplots(figsize=(6, 4), layout='constrained')
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x))
ax.set_title('Single Subplot')
ax.set_xlabel('x')
ax.set_ylabel('sin(x)')
ax.grid(True, alpha=0.3)
plt.show()
import numpy as np
# 创建单个子图(最常用写法)
fig, ax = plt.subplots(figsize=(6, 4), layout='constrained')
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x))
ax.set_title('Single Subplot')
ax.set_xlabel('x')
ax.set_ylabel('sin(x)')
ax.grid(True, alpha=0.3)
plt.show()
示例 2:一行多列 / 一列多行
实例
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
# 一行三列
fig, axes = plt.subplots(1, 3, figsize=(12, 4),
layout='constrained')
# axes 是一维数组
axes[0].plot(x, np.sin(x), color='blue')
axes[0].set_title('sin(x)')
axes[1].plot(x, np.cos(x), color='red')
axes[1].set_title('cos(x)')
axes[2].plot(x, np.tan(x), color='green')
axes[2].set_title('tan(x)')
axes[2].set_ylim(-5, 5) # 限制 y 范围
for ax in axes:
ax.set_xlabel('x')
ax.grid(True, alpha=0.3)
fig.suptitle('Three Subplots in One Row', fontsize=14)
plt.show()
import numpy as np
x = np.linspace(0, 10, 100)
# 一行三列
fig, axes = plt.subplots(1, 3, figsize=(12, 4),
layout='constrained')
# axes 是一维数组
axes[0].plot(x, np.sin(x), color='blue')
axes[0].set_title('sin(x)')
axes[1].plot(x, np.cos(x), color='red')
axes[1].set_title('cos(x)')
axes[2].plot(x, np.tan(x), color='green')
axes[2].set_title('tan(x)')
axes[2].set_ylim(-5, 5) # 限制 y 范围
for ax in axes:
ax.set_xlabel('x')
ax.grid(True, alpha=0.3)
fig.suptitle('Three Subplots in One Row', fontsize=14)
plt.show()
示例 3:2x2 网格 + 宽高比例
实例
import matplotlib.pyplot as plt
import numpy as np
# 宽高比:第1行更高,第2列更宽
fig, axes = plt.subplots(2, 2,
figsize=(10, 8),
width_ratios=[1, 2], # 第2列宽度是第1列的2倍
height_ratios=[2, 1], # 第1行高度是第2行的2倍
layout='constrained',
sharex='col', # 每列共享 x 轴
sharey='row') # 每行共享 y 轴
x = np.linspace(0, 10, 100)
# axes 是二维数组,axes[row, col]
axes[0, 0].plot(x, np.sin(x))
axes[0, 0].set_title('sin(x)')
axes[0, 1].plot(x, np.cos(x), 'orange')
axes[0, 1].set_title('cos(x)')
axes[1, 0].plot(x, np.sin(2*x), 'green')
axes[1, 0].set_title('sin(2x)')
axes[1, 1].plot(x, np.cos(2*x), 'red')
axes[1, 1].set_title('cos(2x)')
fig.suptitle('2x2 Grid with Width/Height Ratios', fontsize=14)
plt.show()
import numpy as np
# 宽高比:第1行更高,第2列更宽
fig, axes = plt.subplots(2, 2,
figsize=(10, 8),
width_ratios=[1, 2], # 第2列宽度是第1列的2倍
height_ratios=[2, 1], # 第1行高度是第2行的2倍
layout='constrained',
sharex='col', # 每列共享 x 轴
sharey='row') # 每行共享 y 轴
x = np.linspace(0, 10, 100)
# axes 是二维数组,axes[row, col]
axes[0, 0].plot(x, np.sin(x))
axes[0, 0].set_title('sin(x)')
axes[0, 1].plot(x, np.cos(x), 'orange')
axes[0, 1].set_title('cos(x)')
axes[1, 0].plot(x, np.sin(2*x), 'green')
axes[1, 0].set_title('sin(2x)')
axes[1, 1].plot(x, np.cos(2*x), 'red')
axes[1, 1].set_title('cos(2x)')
fig.suptitle('2x2 Grid with Width/Height Ratios', fontsize=14)
plt.show()
示例 4:sharex 和 sharey 共享轴
实例
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
# 共享 x 轴,方便比较时间序列
fig, axes = plt.subplots(3, 1, figsize=(8, 6),
sharex=True, # 共享 x 轴
layout='constrained')
t = np.linspace(0, 20, 200)
# 三个子图共享 x 轴,共同时刻对齐
axes[0].plot(t, np.sin(t), 'blue')
axes[0].set_ylabel('Signal 1')
axes[0].grid(True, alpha=0.3)
axes[1].plot(t, np.cos(t * 1.5), 'green')
axes[1].set_ylabel('Signal 2')
axes[1].grid(True, alpha=0.3)
axes[2].plot(t, np.sin(t * 0.7) + np.cos(t * 1.3), 'red')
axes[2].set_xlabel('Time (s)')
axes[2].set_ylabel('Signal 3')
axes[2].grid(True, alpha=0.3)
fig.suptitle('Shared X-Axis: Three Time Series', fontsize=14)
plt.show()
import numpy as np
np.random.seed(42)
# 共享 x 轴,方便比较时间序列
fig, axes = plt.subplots(3, 1, figsize=(8, 6),
sharex=True, # 共享 x 轴
layout='constrained')
t = np.linspace(0, 20, 200)
# 三个子图共享 x 轴,共同时刻对齐
axes[0].plot(t, np.sin(t), 'blue')
axes[0].set_ylabel('Signal 1')
axes[0].grid(True, alpha=0.3)
axes[1].plot(t, np.cos(t * 1.5), 'green')
axes[1].set_ylabel('Signal 2')
axes[1].grid(True, alpha=0.3)
axes[2].plot(t, np.sin(t * 0.7) + np.cos(t * 1.3), 'red')
axes[2].set_xlabel('Time (s)')
axes[2].set_ylabel('Signal 3')
axes[2].grid(True, alpha=0.3)
fig.suptitle('Shared X-Axis: Three Time Series', fontsize=14)
plt.show()
示例 5:极坐标子图
实例
import matplotlib.pyplot as plt
import numpy as np
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4),
subplot_kw={'projection': 'polar'}, # 两个都是极坐标
layout='constrained')
theta = np.linspace(0, 2 * np.pi, 100)
# 左图:玫瑰线
r1 = np.abs(np.sin(3 * theta))
ax1.plot(theta, r1, color='blue', linewidth=2)
ax1.set_title('Polar: Rose Curve (r=|sin(3θ)|)')
# 右图:阿基米德螺旋
r2 = theta / 6
ax2.plot(theta, r2, color='red', linewidth=2)
ax2.set_title('Polar: Archimedean Spiral')
plt.show()
import numpy as np
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4),
subplot_kw={'projection': 'polar'}, # 两个都是极坐标
layout='constrained')
theta = np.linspace(0, 2 * np.pi, 100)
# 左图:玫瑰线
r1 = np.abs(np.sin(3 * theta))
ax1.plot(theta, r1, color='blue', linewidth=2)
ax1.set_title('Polar: Rose Curve (r=|sin(3θ)|)')
# 右图:阿基米德螺旋
r2 = theta / 6
ax2.plot(theta, r2, color='red', linewidth=2)
ax2.set_title('Polar: Archimedean Spiral')
plt.show()
常见问题
squeeze 参数有什么用?
squeeze=True(默认)时:subplots(1,1) 返回 ax(不是 [ax]),subplots(1,3) 返回一维数组。
squeeze=False 时始终返回二维数组(不论行列数),适合需要统一处理的场景。
subplot_kw 和 gridspec_kw 的区别?
subplot_kw 传递给每个 Axes 创建函数,如 projection='polar'。
gridspec_kw 传递给 GridSpec 布局管理器,如 hspace=0.4(子图垂直间距)。

Matplotlib 参考文档