现在位置: 首页 > Matplotlib 教程 > 正文

Matplotlib subplots() 函数


Matplotlib 参考文档 Matplotlib 参考文档

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)

参数说明

参数类型说明
nrowsint子图行数,默认 1
ncolsint子图列数,默认 1
sharex / shareybool 或 str是否共享 x/y 轴。可传入 'all'/'row'/'col'/'none' 或布尔值
squeezebool若为 True,单行/单列时自动去除多余维度,默认 True
width_ratioslist各列宽度比例,如 [1, 2] 表示第 2 列是第 1 列的 2 倍宽
height_ratioslist各行高度比例,如 [2, 1] 表示第 1 行是第 2 行的 2 倍高
subplot_kwdict传递给子图创建的参数,如 dict(projection='polar') 创建极坐标子图
gridspec_kwdict传递给 GridSpec 的参数,如 dict(hspace=0.3, wspace=0.3) 设置子图间距
**fig_kwdict传递给 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()

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

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

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

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

常见问题

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 参考文档 Matplotlib 参考文档