ZetCode

Matplotlib 子图

最后修改于 2025 年 2 月 25 日

Matplotlib 是一个强大的 Python 库,用于创建静态、动画和交互式可视化。子图允许您在单个图形中显示多个绘图。本教程介绍如何使用 Matplotlib 创建和自定义子图。

子图非常适合比较多个数据集或可视化同一数据集的不同方面。 Matplotlib 提供了一个灵活且易于使用的界面来创建具有自定义功能的子图。

基本子图

此示例演示如何创建基本的 2x2 子图网格。

basic_subplots.py
import matplotlib.pyplot as plt
import numpy as np

# Data
x = np.linspace(0, 10, 100)

# Create a 2x2 grid of subplots
fig, axs = plt.subplots(2, 2)

# Plot data in each subplot
axs[0, 0].plot(x, np.sin(x))
axs[0, 0].set_title("Sine Wave")

axs[0, 1].plot(x, np.cos(x))
axs[0, 1].set_title("Cosine Wave")

axs[1, 0].plot(x, np.tan(x))
axs[1, 0].set_title("Tangent Wave")

axs[1, 1].plot(x, np.exp(x))
axs[1, 1].set_title("Exponential Curve")

# Adjust layout
plt.tight_layout()

# Display the figure
plt.show()

代码示例使用 matplotlib.pyplot 库创建一个 2x2 的子图网格,显示不同的数学函数。首先,它使用 numpy.linspace 生成 0 到 10 之间 100 个均匀间隔的点。

然后,它创建一个包含四个子图 (axs) 的图形,并在每个子图上分别绘制正弦波、余弦波、正切波和指数曲线,同时还为每个绘图添加标题。 最后,它调整图形的布局以确保绘图不重叠,并使用 plt.show 显示图形。

自定义子图

此示例演示如何使用共享轴、标题和标签自定义子图。

custom_subplots.py
import matplotlib.pyplot as plt
import numpy as np

# Data
x = np.linspace(0, 10, 100)

# Create a 2x1 grid of subplots with shared X-axis
fig, axs = plt.subplots(2, 1, sharex=True)

# Plot data in each subplot
axs[0].plot(x, np.sin(x), color="blue")
axs[0].set_title("Sine Wave")
axs[0].set_ylabel("Amplitude")

axs[1].plot(x, np.cos(x), color="red")
axs[1].set_title("Cosine Wave")
axs[1].set_xlabel("X-axis")
axs[1].set_ylabel("Amplitude")

# Adjust layout
plt.tight_layout()

# Display the figure
plt.show()

sharex=True 参数确保子图共享同一个 X 轴。 标题和标签使用 set_titleset_xlabelset_ylabel 添加。

不均匀子图

此示例演示如何使用 GridSpec 创建具有不均匀布局的子图。

uneven_subplots.py
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.gridspec import GridSpec

# Data
x = np.linspace(0, 10, 100)

# Create a figure with uneven subplots
fig = plt.figure()
gs = GridSpec(2, 2, figure=fig)

# Create subplots
ax1 = fig.add_subplot(gs[0, :])  # Top row, full width
ax2 = fig.add_subplot(gs[1, 0])  # Bottom left
ax3 = fig.add_subplot(gs[1, 1])  # Bottom right

# Plot data in each subplot
ax1.plot(x, np.sin(x))
ax1.set_title("Sine Wave")

ax2.plot(x, np.cos(x))
ax2.set_title("Cosine Wave")

ax3.plot(x, np.tan(x))
ax3.set_title("Tangent Wave")

# Adjust layout
plt.tight_layout()

# Display the figure
plt.show()

该示例使用 Matplotlib 中的 GridSpec 模块创建一个包含三个排列不均匀的子图的图形。 顶行子图跨越图形的整个宽度,并显示一个标记为“正弦波”的正弦波。 底行包含两个子图:左侧子图显示一个标记为“余弦波”的余弦波,而右侧子图显示一个标记为“正切波”的正切波。

tight_layout 函数用于调整子图之间的间距,以获得更简洁的外观。 生成的图形以可视方式表示 x 轴范围从 0 到 10 的数学函数正弦、余弦和正切。

具有不同大小的子图

此示例演示如何使用 subplot2grid 创建具有不同大小的子图。

different_sized_subplots.py
import matplotlib.pyplot as plt
import numpy as np

# Data
x = np.linspace(0, 10, 100)

# Create a figure with subplots of different sizes
plt.figure()

# First subplot (large)
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3)
ax1.plot(x, np.sin(x))
ax1.set_title("Sine Wave")

# Second subplot (small)
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
ax2.plot(x, np.cos(x))
ax2.set_title("Cosine Wave")

# Third subplot (small)
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
ax3.plot(x, np.tan(x))
ax3.set_title("Tangent Wave")

# Fourth subplot (small)
ax4 = plt.subplot2grid((3, 3), (2, 0))
ax4.plot(x, np.exp(x))
ax4.set_title("Exponential Curve")

# Fifth subplot (small)
ax5 = plt.subplot2grid((3, 3), (2, 1))
ax5.plot(x, np.log(x + 1))
ax5.set_title("Logarithmic Curve")

# Adjust layout
plt.tight_layout()

# Display the figure
plt.show()

subplot2grid 函数允许通过指定网格布局和每个子图的位置来创建不同大小的子图。

带有标签和标题的子图

此示例演示如何创建带有标签和标题的子图网格。

subplots_with_labels.py
import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(3, 3, figsize=(15, 8), sharex=True, sharey=True)

for i, ax in enumerate(axs.flat):
    ax.scatter(*np.random.normal(size=(2, 200)))
    ax.set_title(f'Title {i+1}')

# Set labels
plt.setp(axs[-1, :], xlabel='x axis label')
plt.setp(axs[:, 0], ylabel='y axis label')

plt.savefig('subplots.png')

plt.setp 函数用于设置子图的 X 和 Y 轴的标签。 每个子图都有一个唯一的标题。

共享 X 轴

此示例演示如何创建共享 X 轴的子图。

sharing_x_axis.py
import matplotlib.pyplot as plt

data = {'FreeBSD': 4, 'NetBSD': 1, 'Linux': 12, 'Windows': 6, 'Apple': 2}
keys = list(data.keys())
vals = list(data.values())

fig, axs = plt.subplots(3, 1, figsize=(4, 10), sharex=True)
axs[0].bar(keys, vals)
axs[1].scatter(keys, vals)
axs[2].plot(keys, vals)

fig.suptitle('Operating systems in lab')
plt.savefig('subplots.png')

sharex=True 参数确保所有子图共享同一个 X 轴。 fig.suptitle 函数向整个图形添加标题。

分别创建每个子图

此示例演示如何使用 subplot 函数分别创建每个子图。

separate_subplots.py
import matplotlib.pyplot as plt
import numpy as np

x = np.array([0, 1, 2, 3])
y = np.array([6, 8, 2, 11])

plt.subplot(2, 3, 1)
plt.plot(x, y)

x = np.array([0, 1, 2, 3])
y = np.array([15, 25, 35, 45])

plt.suptitle('Subplots')

plt.subplot(2, 3, 2)
plt.plot(x, y)

x = np.array([0, 1, 2, 3])
y = np.array([2, 9, 11, 11])

plt.subplot(2, 3, 3)
plt.plot(x, y)

x = np.array([0, 1, 2, 3])
y = np.array([11, 22, 33, 55])

plt.subplot(2, 3, 4)
plt.plot(x, y)

x = np.array([0, 1, 2, 3])
y = np.array([13, 18, 11, 10])

plt.subplot(2, 3, 5)
plt.plot(x, y)

x = np.array([0, 1, 2, 3])
y = np.array([10, 20, 30, 40])

plt.subplot(2, 3, 6)
plt.plot(x, y)

plt.savefig('subplots2.png')

subplot 函数用于单独创建每个子图。 suptitle 函数向整个图形添加标题。

子图的最佳实践

来源

Matplotlib 子图文档

在本文中,我们探讨了如何使用 Matplotlib 创建和自定义子图,包括基本子图、共享轴、不均匀布局和不同大小的子图。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出 所有 Python 教程