如何调整Matplotlib子图间空白?自定义指定子图间距方案
调整Matplotlib子图间距的解决方案
嘿,这个需求用Matplotlib的gridspec工具来实现最精准啦,它能帮你灵活控制不同组子图之间的间距,完美达到你要的效果——消除第1&2、3&4子图间的空白,同时拉大第2&3子图的间距。我给你写了完整的代码示例,直接就能运行:
import matplotlib.pyplot as plt import numpy as np from matplotlib.gridspec import GridSpec, GridSpecFromSubplotSpec # 生成示例数据 x = np.linspace(0, 2 * np.pi, 400) y = np.sin(x ** 2) # 创建画布 fig = plt.figure(figsize=(10, 10)) # 先把画布分成上下两大组,组之间设置较大间距(这里设为0.5,可按需调整) gs = GridSpec(2, 1, figure=fig, height_ratios=[1, 1], hspace=0.5) # 第一组:包含第1、2个子图,子图间间距设为0 gs_top = GridSpecFromSubplotSpec(2, 1, subplot_spec=gs[0], hspace=0) ax0 = fig.add_subplot(gs_top[0]) ax1 = fig.add_subplot(gs_top[1], sharex=ax0) # 第二组:包含第3、4个子图,子图间间距设为0 gs_bottom = GridSpecFromSubplotSpec(2, 1, subplot_spec=gs[1], hspace=0) ax2 = fig.add_subplot(gs_bottom[0], sharex=ax0) ax3 = fig.add_subplot(gs_bottom[1], sharex=ax0) # 绘制图形并设置标题 ax0.plot(x, y) ax0.set_title('Panel: A') ax1.plot(x, y**2) ax1.set_title('Panel: B') ax2.plot(x, -y) ax2.set_title('Panel: C') ax3.plot(x, -y**2) ax3.set_title('Panel: D') # 隐藏上方子图的x轴标签,避免重复显示,让布局更整洁 ax0.tick_params(labelbottom=False) ax1.tick_params(labelbottom=False) ax2.tick_params(labelbottom=False) plt.show()
关键逻辑说明:
- 先用
GridSpec把整个画布拆成上下两个大区块,hspace=0.5就是控制这两个区块(对应第2和第3子图的上下区域)的间距,数值越大间距越宽,你可以根据自己的需求修改这个值。 - 每个大区块内部再用
GridSpecFromSubplotSpec拆成两行,hspace=0直接消除了同组内子图的空白。 - 通过
sharex参数保证所有子图的x轴刻度一致,再隐藏上方子图的x轴标签,让整体布局更清爽。
如果你不想用gridspec,也可以用基础的subplots_adjust配合手动调整边距,不过灵活性稍差一点,代码示例供你参考:
import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 2 * np.pi, 400) y = np.sin(x ** 2) f, ax = plt.subplots(4, figsize=(10,10), sharex=True) ax[0].plot(x, y) ax[0].set_title('Panel: A') ax[1].plot(x, y**2) ax[1].set_title('Panel: B') ax[2].plot(x, -y) ax[2].set_title('Panel: C') ax[3].plot(x, -y**2) ax[3].set_title('Panel: D') # 先把所有子图的默认间距设为0 plt.subplots_adjust(hspace=0) # 手动给第2个子图底部、第3个子图顶部添加间距 ax[1].margin(0, 0.5) ax[2].margin(0.5, 0) # 隐藏重复的x轴标签 ax[0].tick_params(labelbottom=False) ax[1].tick_params(labelbottom=False) ax[2].tick_params(labelbottom=False) plt.show()
内容的提问来源于stack exchange,提问作者user5121229




