如何居中第一行子图并使色条与第二行子图等高?
子图布局与尺寸异常问题解决
问题背景
需要绘制一个2行布局的子图,核心需求:
- 第一行仅1个子图,要求居中显示
- 色条高度需与第二行子图保持一致
目前存在两个待解决问题:
A. 如何让第一行子图灵活居中(原手动设置ax1.set_position的方式不够通用)
B. 第二行最右侧子图尺寸明显小于其他子图,如何修复
原代码核心问题:
subplot2grid的列跨度设置与总列数不匹配,导致布局预留空间失衡plt.show()放在循环内部,多次触发画布渲染干扰整体布局- 手动设置子图位置破坏了自动布局的协调性,挤压了第二行子图的空间
修复后的完整代码
import matplotlib.pyplot as plt import numpy as np # 模拟数据(请替换为实际业务数据) degree = [0,30,45,60,90] arr_x = np.array([1,2,3,4]) arr_y = np.array([1,2,3,4]) labels = ['S1','S2','S3','S4'] spec = np.random.rand(10,10) extent = [0, 10, 0, 10] jj = 500 fig = plt.figure(figsize=(8,4), dpi=100) # 创建2行5列的网格,行高比例1:1 gs = fig.add_gridspec(2, 5, height_ratios=[1,1]) # 第一行居中子图:占据第2-4列(共3列),自动实现居中 ax1 = fig.add_subplot(gs[0, 1:4]) for i, label in enumerate(labels): ax1.scatter(arr_x[i], arr_y[i], s=60, c='r', marker='o') ax1.annotate(label, xy=(arr_x[i], arr_y[i]), xytext=(1,-17), textcoords='offset points', ha='center') for x,y in zip(arr_x, arr_y): label = f"({x},{y})" ax1.annotate(label, xy=(x,y), xytext=(8,5), textcoords='offset points', ha='center') ax1.set_xlim(np.min(arr_x)-2, np.max(arr_x)+2) ax1.set_ylim(np.min(arr_y)-2, np.max(arr_y)+2) ax1.set_xlabel(" $X$-axis", fontsize=18) ax1.set_ylabel("$Y$-axis", fontsize=18) ax1.set_title(f'Sensor position in $X-Y$ coordinates', loc='left') # 第二行5个等尺寸子图 ax_list = [] for deg_num in range(len(degree)): theta = degree[deg_num] ax2 = fig.add_subplot(gs[1, deg_num]) c = ax2.imshow(spec, cmap='seismic', vmin=spec.min(), vmax=spec.max(), extent=extent, interpolation='nearest', origin='lower') ax2.set_xlabel("Wavenumber, $K_x$ [rad/m]", fontsize=12) ax2.set_ylabel("Wavenumber,$K_y$ [rad/m]", fontsize=12) ax2.set_title(f'$\phi$={theta} deg. @{jj}Hz') ax_list.append(ax2) # 自动调整子图间距,避免标签挤压 plt.tight_layout() # 添加与第二行子图高度匹配的色条 cbar_ax = fig.add_axes([0.92, 0.12, 0.02, 0.35]) # 参数:[左边界, 下边界, 宽度, 高度] fig.colorbar(c, cax=cbar_ax) cbar_ax.set_ylabel(f'Spatial Spectrum at {jj}Hz', rotation=90, fontsize=12, labelpad=1) plt.show()
关键修复说明
第一行子图居中实现:
- 用
gridspec替代subplot2grid,通过gs[0, 1:4]让子图占据中间3列,无需手动计算位置即可自动居中 - 网格布局逻辑更清晰,适配不同画布尺寸时无需手动调整参数
- 用
第二行子图尺寸统一:
- 移除循环内的
plt.show(),避免多次创建画布破坏布局结构 - 基于
gridspec的统一网格划分,保证每个子图占据相同宽度的列空间 plt.tight_layout()自动调整子图间距,避免坐标轴标签挤压导致的尺寸异常
- 移除循环内的
色条高度匹配:
- 通过
fig.add_axes()手动指定色条的位置和高度,精准匹配第二行子图的垂直范围,替代原代码中fraction参数的模糊控制
- 通过
内容的提问来源于stack exchange,提问作者Alan22
相关产品推荐
相关产品推荐

