Matplotlib 中如何并排放置多个图表:全面指南

Matplotlib 中如何并排放置多个图表:全面指南

参考:Place plots side by side in Matplotlib

Matplotlib 是 Python 中最流行的数据可视化库之一,它提供了强大的工具来创建各种类型的图表和绘图。在数据分析和科学研究中,我们经常需要比较多个图表或在同一个视图中展示多个相关的图形。本文将详细介绍如何在 Matplotlib 中并排放置多个图表,包括使用 subplot()、gridspec、add_axes() 等方法,以及如何调整布局、共享轴和自定义图表样式。

1. 使用 subplot() 方法

subplot() 方法是 Matplotlib 中最基本和常用的创建子图的方法。它允许我们在一个图形窗口中创建多个子图,并按照网格布局排列它们。

1.1 基本用法

以下是使用 subplot() 创建并排图表的基本示例:

import matplotlib.pyplot as plt
import numpy as np

# 创建示例数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

# 创建图形和子图
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))

# 在第一个子图中绘制 sin 函数
ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')

# 在第二个子图中绘制 cos 函数
ax2.plot(x, y2)
ax2.set_title('Cos Function - how2matplotlib.com')

# 调整子图之间的间距
plt.tight_layout()

# 显示图形
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们使用 plt.subplots(1, 2) 创建了一个包含两个并排子图的图形。figsize=(10, 4) 参数用于设置整个图形的大小。我们使用返回的 ax1ax2 对象来在各自的子图上绘制数据。

1.2 调整子图大小和间距

我们可以使用 gridspec_kw 参数来调整子图的大小和间距:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4), 
                               gridspec_kw={'width_ratios': [2, 1], 'wspace': 0.3})

ax1.plot(x, y1)
ax1.set_title('Sin Function (Wider) - how2matplotlib.com')

ax2.plot(x, y2)
ax2.set_title('Cos Function - how2matplotlib.com')

plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们使用 width_ratios 参数来设置子图的宽度比例,使第一个子图比第二个宽两倍。wspace 参数用于调整子图之间的水平间距。

1.3 创建不同行列的子图

subplot() 方法也允许我们创建多行多列的子图布局:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
y4 = x**2

fig, axs = plt.subplots(2, 2, figsize=(10, 8))

axs[0, 0].plot(x, y1)
axs[0, 0].set_title('Sin Function - how2matplotlib.com')

axs[0, 1].plot(x, y2)
axs[0, 1].set_title('Cos Function - how2matplotlib.com')

axs[1, 0].plot(x, y3)
axs[1, 0].set_title('Tan Function - how2matplotlib.com')

axs[1, 1].plot(x, y4)
axs[1, 1].set_title('Square Function - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

这个例子创建了一个 2×2 的子图网格,我们可以使用 axs[row, col] 来访问每个子图。

2. 使用 GridSpec

GridSpec 提供了更灵活的方式来创建复杂的子图布局。它允许我们精确控制每个子图的位置和大小。

2.1 基本用法

以下是使用 GridSpec 创建并排图表的基本示例:

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

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig = plt.figure(figsize=(10, 4))
gs = gridspec.GridSpec(1, 2)

ax1 = fig.add_subplot(gs[0, 0])
ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')

ax2 = fig.add_subplot(gs[0, 1])
ax2.plot(x, y2)
ax2.set_title('Cos Function - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们首先创建一个图形对象,然后使用 GridSpec 创建一个 1×2 的网格。我们使用 add_subplot() 方法将子图添加到指定的网格位置。

2.2 创建不规则布局

GridSpec 的强大之处在于它可以创建不规则的子图布局:

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

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)

fig = plt.figure(figsize=(12, 8))
gs = gridspec.GridSpec(2, 2)

ax1 = fig.add_subplot(gs[0, :])
ax1.plot(x, y1)
ax1.set_title('Sin Function (Full Width) - how2matplotlib.com')

ax2 = fig.add_subplot(gs[1, 0])
ax2.plot(x, y2)
ax2.set_title('Cos Function - how2matplotlib.com')

ax3 = fig.add_subplot(gs[1, 1])
ax3.plot(x, y3)
ax3.set_title('Tan Function - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们创建了一个 2×2 的网格,但第一个子图占据了整个顶行(gs[0, :]),而底部有两个并排的子图。

2.3 调整子图间距

GridSpec 还允许我们精细调整子图之间的间距:

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

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig = plt.figure(figsize=(10, 4))
gs = gridspec.GridSpec(1, 2, width_ratios=[1, 1.5], wspace=0.4)

ax1 = fig.add_subplot(gs[0])
ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')

ax2 = fig.add_subplot(gs[1])
ax2.plot(x, y2)
ax2.set_title('Cos Function (Wider) - how2matplotlib.com')

plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们使用 width_ratios 参数来设置子图的宽度比例,使第二个子图比第一个宽 1.5 倍。wspace 参数用于增加子图之间的水平间距。

3. 使用 add_axes() 方法

add_axes() 方法提供了最灵活的方式来放置子图,允许我们精确指定子图在图形中的位置和大小。

3.1 基本用法

以下是使用 add_axes() 创建并排图表的基本示例:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig = plt.figure(figsize=(10, 4))

ax1 = fig.add_axes([0.1, 0.1, 0.4, 0.8])
ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')

ax2 = fig.add_axes([0.55, 0.1, 0.4, 0.8])
ax2.plot(x, y2)
ax2.set_title('Cos Function - how2matplotlib.com')

plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,add_axes() 方法的参数是一个列表 [left, bottom, width, height],其中所有值都是相对于整个图形的比例(0 到 1)。

3.2 创建嵌套子图

add_axes() 方法的一个优势是它可以轻松创建嵌套的子图:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig = plt.figure(figsize=(10, 4))

# 主子图
ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')

# 嵌套子图
ax2 = fig.add_axes([0.2, 0.6, 0.25, 0.25])
ax2.plot(x, y2)
ax2.set_title('Cos Function', fontsize=10)

plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们在主子图内部创建了一个较小的嵌套子图。

3.3 创建不对称布局

add_axes() 方法还允许我们创建不对称的子图布局:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)

fig = plt.figure(figsize=(12, 4))

ax1 = fig.add_axes([0.05, 0.1, 0.4, 0.8])
ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')

ax2 = fig.add_axes([0.5, 0.1, 0.2, 0.8])
ax2.plot(x, y2)
ax2.set_title('Cos Function - how2matplotlib.com')

ax3 = fig.add_axes([0.75, 0.1, 0.2, 0.8])
ax3.plot(x, y3)
ax3.set_title('Tan Function - how2matplotlib.com')

plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们创建了三个宽度不同的并排子图。

4. 共享轴和调整刻度

在并排放置多个图表时,我们可能希望它们共享相同的 x 轴或 y 轴,或者调整刻度以使比较更容易。

4.1 共享 x 轴

以下是创建共享 x 轴的并排图表的示例:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4), sharex=True)

ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')

ax2.plot(x, y2)
ax2.set_title('Cos Function - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们使用 sharex=True 参数来使两个子图共享相同的 x 轴。

4.2 调整 y 轴刻度

有时我们可能需要调整 y 轴刻度以便更好地比较不同的图表:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = 100 * np.cos(x)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))

ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')
ax1.set_ylim(-1.5, 1.5)

ax2.plot(x, y2)
ax2.set_title('100 * Cos Function - how2matplotlib.com')
ax2.set_ylim(-150, 150)

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们使用 set_ylim() 方法来手动设置每个子图的 y 轴范围,以确保图表的比例合适。

5. 自定义图表样式

当并排放置多个图表时,我们可能希望自定义它们的样式以提高可读性和美观性。

5.1 设置不同的线条样式和颜色

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))

ax1.plot(x, y1, color='red', linestyle='--', linewidth=2)
ax1.set_title('Sin Function - how2matplotlib.com')
ax1.set_facecolor('#f0f0f0')

ax2.plot(x, y2, color='blue', linestyle=':', linewidth=2)
ax2.set_title('Cos Function - how2matplotlib.com')
ax2.set_facecolor('#e0e0e0')

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们为每个子图设置了不同的线条颜色、样式和宽度,并使用 set_facecolor() 方法设置了不同的背景颜色。

5.2 添加图例和网格

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))

ax1.plot(x, y1, label='Sin')
ax1.set_title('Sin Function - how2matplotlib.com')
ax1.legend()
ax1.grid(True, linestyle='--', alpha=0.7)

ax2.plot(x, y2, label='Cos')
ax2.set_title('Cos Function - how2matplotlib.com')
ax2.legend()
ax2.grid(True, linestyle=':', alpha=0.7)

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

这个例子展示了如何为每个子图添加图例和网格。我们使用 legend() 方法添加图例,使用 grid() 方法添加网格线。

5.3 自定义刻度标签

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2*np.pi, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))

ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')
ax1.set_xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi])
ax1.set_xticklabels(['0', 'π/2', 'π', '3π/2', '2π'])

ax2.plot(x, y2)
ax2.set_title('Cos Function - how2matplotlib.com')
ax2.set_xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi])
ax2.set_xticklabels(['0', 'π/2', 'π', '3π/2', '2π'])

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们使用 set_xticks()set_xticklabels() 方法来自定义 x 轴的刻度标签,使用数学符号来表示 π 的倍数。

6. 处理不同类型的图表

在实际应用中,我们可能需要并排放置不同类型的图表,如折线图、散点图、柱状图等。

6.1 组合折线图和散点图

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 50)
y1 = np.sin(x)
y2 = np.random.rand(50)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))

ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')

ax2.scatter(x, y2, color='red', alpha=0.5)
ax2.set_title('Random Scatter - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

这个例子展示了如何在一个图形中并排放置一个折线图和一个散点图。

6.2 组合柱状图和饼图

import matplotlib.pyplot as plt
import numpy as np

categories = ['A', 'B', 'C', 'D']
values = [25, 40, 20, 15]

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))

ax1.bar(categories, values)
ax1.set_title('Bar Chart - how2matplotlib.com')

ax2.pie(values, labels=categories, autopct='%1.1f%%', startangle=90)
ax2.set_title('Pie Chart - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

这个例子展示了如何并排放置一个柱状图和一个饼图,用两种不同的方式来可视化相同的数据。

6.3 组合热图和等高线图

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))

im = ax1.imshow(Z, cmap='viridis', extent=[-5, 5, -5, 5])
ax1.set_title('Heatmap - how2matplotlib.com')
fig.colorbar(im, ax=ax1)

cs = ax2.contour(X, Y, Z, levels=10)
ax2.set_title('Contour Plot - how2matplotlib.com')
ax2.clabel(cs, inline=1, fontsize=10)

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

这个例子展示了如何并排放置一个热图和一个等高线图,用两种不同的方式来可视化二维数据。

7. 高级技巧和注意事项

在使用 Matplotlib 并排放置多个图表时,还有一些高级技巧和注意事项需要考虑。

7.1 使用 constrained_layout

constrained_layout 是一个自动调整子图位置的工具,可以避免标签重叠和其他布局问题:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4), constrained_layout=True)

ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')
ax1.set_xlabel('X axis')
ax1.set_ylabel('Y axis')

ax2.plot(x, y2)
ax2.set_title('Cos Function - how2matplotlib.com')
ax2.set_xlabel('X axis')
ax2.set_ylabel('Y axis')

plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

使用 constrained_layout=True 可以自动调整子图的位置,以确保标签不会重叠。

7.2 处理不同大小的子图

有时我们可能需要创建大小不同的子图:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)

fig = plt.figure(figsize=(12, 8))

gs = fig.add_gridspec(2, 2)

ax1 = fig.add_subplot(gs[0, 0])
ax1.plot(x, y1)
ax1.set_title('Sin Function - how2matplotlib.com')

ax2 = fig.add_subplot(gs[0, 1])
ax2.plot(x, y2)
ax2.set_title('Cos Function - how2matplotlib.com')

ax3 = fig.add_subplot(gs[1, :])
ax3.plot(x, y3)
ax3.set_title('Tan Function - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

在这个例子中,我们使用 GridSpec 创建了三个子图,其中底部的子图跨越了整个宽度。

7.3 处理大量子图

当需要创建大量子图时,可以使用循环来简化代码:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
functions = [np.sin, np.cos, np.tan, np.square]

fig, axs = plt.subplots(2, 2, figsize=(12, 10))
axs = axs.ravel()  # 将二维数组展平为一维

for i, func in enumerate(functions):
    axs[i].plot(x, func(x))
    axs[i].set_title(f'{func.__name__} Function - how2matplotlib.com')
    axs[i].set_xlabel('X axis')
    axs[i].set_ylabel('Y axis')

plt.tight_layout()
plt.show()

Output:

Matplotlib 中如何并排放置多个图表:全面指南

这个例子展示了如何使用循环来创建和自定义多个子图,适用于需要创建大量相似子图的情况。

结论

在 Matplotlib 中并排放置多个图表是一项强大的技能,可以帮助我们更有效地比较和分析数据。通过使用 subplot()、GridSpec 和 add_axes() 等方法,我们可以创建各种复杂的布局。结合自定义样式、共享轴和调整刻度等技巧,我们可以创建出既信息丰富又视觉吸引的图表。

记住,选择合适的布局方法取决于你的具体需求。对于简单的并排布局,subplot() 方法通常就足够了。如果需要更灵活的控制,可以考虑使用 GridSpec。而对于需要精确控制子图位置和大小的情况,add_axes() 方法是最佳选择。

无论使用哪种方法,都要注意保持图表的清晰度和可读性。适当地调整大小、间距和样式,确保你的图表能够有效地传达信息。通过实践和实验,你将能够掌握在 Matplotlib 中创建复杂而美观的多图表布局的艺术。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程