杰瑞科技汇

python subplot 间隔

在 Python 的 Matplotlib 中,调整子图(subplot)之间的间隔是一个非常常见的需求,默认情况下,子图之间的间距可能过小或过大,影响图表的美观性和可读性。

主要有两种方法来控制子图间隔:

  1. plt.tight_layout() (推荐,简单高效):这是最常用、最简单的方法,它会自动调整子图参数,使其填充整个图像区域,并避免标签重叠。
  2. plt.subplots_adjust() (灵活,精确控制):当你需要更精细、更个性化的控制时,这个方法非常有用,可以分别调整左右、上下、左右间距和左右间距。

下面我们详细介绍这两种方法,并提供完整的代码示例。


使用 plt.tight_layout()

tight_layout() 会自动计算并调整子图的位置,确保:

  • 子图之间不会重叠。
  • title)、坐标轴标签(xlabel, ylabel)不会超出图像边界或被截断。

基本用法

在绘制完所有子图后,调用 plt.tight_layout() 即可。

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.sin(x) * np.cos(x)
y4 = x**2
# 创建一个 2x2 的子图
plt.subplot(2, 2, 1)
plt.plot(x, y1)"Sine Wave")
plt.subplot(2, 2, 2)
plt.plot(x, y2)"Cosine Wave")
plt.subplot(2, 2, 3)
plt.plot(x, y3)"Sine * Cosine")
plt.subplot(2, 2, 4)
plt.plot(x, y4)"x^2")
# 调整子图间距,使其更紧凑
plt.tight_layout()
plt.show()

效果tight_layout() 会自动让子图之间的间距变得非常合理,通常比默认间距要好。

tight_layout() 的参数

如果你对自动调整的结果不满意,可以传入一些参数进行微调:

  • pad: 子图边缘与图像边缘之间的间距(以字体大小为单位),默认为 08
  • w_pad: 子图水平方向(宽度)之间的间距,默认为 0
  • h_pad: 子图垂直方向(高度)之间的间距,默认为 0
  • rect: 一个元组 (left, bottom, right, top),指定整个子图区域在图像中的位置,默认为 (0, 0, 1, 1)
# ... (上面的绘图代码保持不变) ...
# 使用参数进行微调
# pad=2.0: 增加子图边缘的间距
# w_pad=4.0: 增加子图水平间距
# h_pad=4.0: 增加子图垂直间距
plt.tight_layout(pad=2.0, w_pad=4.0, h_pad=4.0)
plt.show()

使用 plt.subplots_adjust()

这个方法提供了更底层的控制,让你可以精确地设置子图区域的边距。

主要参数

  • left: 子图区域的左边界(相对于图像宽度的比例)。
  • right: 子图区域的右边界。
  • bottom: 子图区域的下边界。
  • top: 子图区域的上边界。
  • wspace: 子图水平方向(宽度)的间距(相对于子图平均宽度的比例)。
  • hspace: 子图垂直方向(高度)的间距(相对于子图平均高度的比例)。

注意:这些参数的值都在 0 到 1 之间。

基本用法

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.sin(x) * np.cos(x)
y4 = x**2
# 创建一个 2x2 的子图
plt.subplot(2, 2, 1)
plt.plot(x, y1)"Sine Wave")
plt.subplot(2, 2, 2)
plt.plot(x, y2)"Cosine Wave")
plt.subplot(2, 2, 3)
plt.plot(x, y3)"Sine * Cosine")
plt.subplot(2, 2, 4)
plt.plot(x, y4)"x^2")
# 手动调整子图间距
# wspace=0.5: 水平间距为子图平均宽度的50%
# hspace=0.5: 垂直间距为子图平均高度的50%
plt.subplots_adjust(wspace=0.5, hspace=0.5)
plt.show()

效果:你会看到子图之间的间距明显变大了。

更精细的控制

结合 left, right, bottom, top 可以控制整个子图组在图像中的位置和大小。

# ... (上面的绘图代码保持不变) ...
# 更精细的控制
# left=0.1, right=0.9: 整个子图组占据图像宽度10%到90%的区域
# bottom=0.1, top=0.9: 整个子图组占据图像高度10%到90%的区域
# wspace=0.2: 水平间距为子图平均宽度的20%
# hspace=0.3: 垂直间距为子图平均高度的30%
plt.subplots_adjust(left=0.1, right=0.9, bottom=0.1, top=0.9, wspace=0.2, hspace=0.3)
plt.show()

如何选择?以及与其他方法的结合

方法 优点 缺点 适用场景
plt.tight_layout() 简单、快速、通常效果很好,能自动处理标签重叠。 控制力相对较弱,有时无法满足非常个性化的布局需求。 绝大多数情况下的首选,特别是当图表包含标题、标签时。
plt.subplots_adjust() 灵活、精确,可以完全控制子图区域和间距。 需要手动调整参数,稍微复杂一些。 需要创建非对称布局、或在图像周围留出大片空白时。

结合 GridSpec 实现更复杂的布局

subplots_adjust 也不够用时,例如需要创建非均匀的子图网格(比如一个2x1的大图和一个1x1的小图),可以使用 GridSpec

import matplotlib.pyplot as plt
import numpy as np
# 创建一个 3x2 的网格布局
fig = plt.figure(figsize=(8, 8))
gs = fig.add_gridspec(3, 2)
# 在第一行创建一个跨两列的大图
ax1 = fig.add_subplot(gs[0, :])
ax1.plot(np.random.rand(50))
ax1.set_title('Big Plot (Spanning 2 columns)')
# 在第二行第一列创建一个图
ax2 = fig.add_subplot(gs[1, 0])
ax2.plot(np.random.rand(50))
ax2.set_title('Plot 1')
# 在第二行第二列创建一个图
ax3 = fig.add_subplot(gs[1, 1])
ax3.plot(np.random.rand(50))
ax3.set_title('Plot 2')
# 在第三行第一列创建一个图
ax4 = fig.add_subplot(gs[2, 0])
ax4.plot(np.random.rand(50))
ax4.set_title('Plot 3')
# 在第三行第二列创建一个图
ax5 = fig.add_subplot(gs[2, 1])
ax5.plot(np.random.rand(50))
ax5.set_title('Plot 4')
# 对整个图像使用 tight_layout
fig.tight_layout()
plt.show()
  1. plt.tight_layout() 开始:它通常是解决子图间距问题的最快、最简单的方法。
  2. 如果需要微调:使用 tight_layout(pad=..., w_pad=..., h_pad=...)
  3. 如果需要完全控制:使用 plt.subplots_adjust(wspace=..., hspace=..., ...)
  4. 对于复杂布局:学习并使用 GridSpec,它提供了最强大的布局能力。
分享:
扫描分享到社交APP
上一篇
下一篇