You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何居中第一行子图并使色条与第二行子图等高?

子图布局与尺寸异常问题解决

问题背景

需要绘制一个2行布局的子图,核心需求:

  • 第一行仅1个子图,要求居中显示
  • 色条高度需与第二行子图保持一致

目前存在两个待解决问题:
A. 如何让第一行子图灵活居中(原手动设置ax1.set_position的方式不够通用)
B. 第二行最右侧子图尺寸明显小于其他子图,如何修复

原代码核心问题:

  1. subplot2grid的列跨度设置与总列数不匹配,导致布局预留空间失衡
  2. plt.show()放在循环内部,多次触发画布渲染干扰整体布局
  3. 手动设置子图位置破坏了自动布局的协调性,挤压了第二行子图的空间

修复后的完整代码

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()

关键修复说明

  1. 第一行子图居中实现:

    • 用gridspec替代subplot2grid,通过gs[0, 1:4]让子图占据中间3列,无需手动计算位置即可自动居中
    • 网格布局逻辑更清晰,适配不同画布尺寸时无需手动调整参数
  2. 第二行子图尺寸统一:

    • 移除循环内的plt.show(),避免多次创建画布破坏布局结构
    • 基于gridspec的统一网格划分,保证每个子图占据相同宽度的列空间
    • plt.tight_layout()自动调整子图间距,避免坐标轴标签挤压导致的尺寸异常
  3. 色条高度匹配:

    • 通过fig.add_axes()手动指定色条的位置和高度,精准匹配第二行子图的垂直范围,替代原代码中fraction参数的模糊控制

内容的提问来源于stack exchange,提问作者Alan22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:25:38