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

Matplotlib左下角子图无法呈正方形及标题位置异常问题咨询

问题:Matplotlib子图布局异常(左下角子图非正方形、标题位置过高)

尝试构建2×2子图布局,要求左下角子图为完美正方形,编写了如下代码:

import matplotlib.pyplot as plt
import numpy as np

fig=plt.figure()
ax=np.empty((2,2,),dtype=object)
ax[1][0]=fig.add_subplot(2,2,3)
ax[0][0]=fig.add_subplot(2,2,1,sharex=ax[1][0])
ax[1][1]=fig.add_subplot(2,2,4,sharey=ax[1][0])
ax[0][1]=fig.add_subplot(2,2,2,sharex=ax[1][1],sharey=ax[0][0])
plt.subplots_adjust(hspace=0,wspace=0)
old_position,old_position2,old_position3,old_position4=list(ax[0][0].get_position().bounds),list(ax[1][1].get_position().bounds),list(ax[1][0].get_position().bounds),list(ax[0][1].get_position().bounds)
old_position[-1]=old_position[-1]/2
old_position2[-2]=old_position2[-2]/2
old_position3[-1]=old_position3[-2]
old_position4[-1]=old_position4[-1]/2
old_position4[-2]=old_position4[-2]/2
ax[0][0].set_position(old_position)
ax[1][1].set_position(old_position2)
ax[1][0].set_position(old_position3)
ax[0][1].set_position(old_position4)
ax[0][0].xaxis.set_visible(False)
ax[0][1].xaxis.set_visible(False)
ax[1][1].yaxis.set_visible(False)
ax[0][1].yaxis.set_visible(False)
#plot stuff onto axes objects
plt.suptitle('Test')
plt.show()

代码中设置左下角子图的位置参数old_position3为[0.125, 0.10999999999999999, 0.38749999999999996, 0.38749999999999996],宽高维度均为0.3874,理论上应呈现正方形,但实际显示时宽高比约为3/5,并非正方形;同时图的suptitle位置过高,仍沿用旧布局的位置。


异常原因

  1. 归一化坐标与画布比例不匹配:get_position().bounds返回的是基于整个画布的归一化坐标(范围0-1),如果画布本身不是正方形,归一化的宽高数值相等时,对应的实际像素宽高并不相等。比如画布是宽屏比例,相同归一化数值的宽度对应的像素数会远大于高度,视觉上就不是正方形。
  2. 标题位置未随布局更新:suptitle默认基于初始子图布局计算位置,手动调整子图位置后,标题不会自动重新适配,所以会停留在原布局的顶部区域。

解决办法

1. 让左下角子图呈现视觉正方形

方法一:使用正方形画布

创建画布时指定宽高相等的尺寸,这样归一化坐标的宽高相等就对应视觉上的正方形:

fig = plt.figure(figsize=(8, 8))  # 宽高均为8英寸的正方形画布

方法二:强制子图坐标轴比例为1

给左下角子图设置aspect='equal',强制坐标轴的宽高比为1,不管画布比例如何,子图都会呈现正方形:

ax[1][0].set_aspect('equal', adjustable='box')

方法三:基于画布尺寸计算对应高度

如果需要保留非正方形画布,可通过画布实际尺寸计算子图的归一化高度,确保实际像素宽高相等:

fig = plt.figure(figsize=(10, 6))
fig_width, fig_height = fig.get_size_inches()
subplot_width = old_position3[2]
# 计算对应归一化高度,保证实际像素宽高一致
subplot_height = subplot_width * fig_width / fig_height
old_position3[3] = subplot_height
ax[1][0].set_position(old_position3)

2. 调整suptitle位置

方法一:手动设置标题垂直位置

通过y参数调整标题的垂直位置,值越小越靠下:

plt.suptitle('Test', y=0.95)  # 根据实际布局调整y值

方法二:用tight_layout自动适配

调用tight_layout并通过rect参数预留标题空间,让标题自动适配新布局:

plt.tight_layout(rect=[0, 0, 1, 0.95])  # rect=[左, 下, 右, 上],预留顶部空间给标题
plt.suptitle('Test')

优化后的完整代码示例

import matplotlib.pyplot as plt
import numpy as np

# 使用正方形画布
fig = plt.figure(figsize=(8, 8))
ax = np.empty((2,2), dtype=object)

ax[1][0] = fig.add_subplot(2,2,3)
ax[0][0] = fig.add_subplot(2,2,1, sharex=ax[1][0])
ax[1][1] = fig.add_subplot(2,2,4, sharey=ax[1][0])
ax[0][1] = fig.add_subplot(2,2,2, sharex=ax[1][1], sharey=ax[0][0])

plt.subplots_adjust(hspace=0, wspace=0)

# 调整子图位置
old_pos = list(ax[0][0].get_position().bounds)
old_pos2 = list(ax[1][1].get_position().bounds)
old_pos3 = list(ax[1][0].get_position().bounds)
old_pos4 = list(ax[0][1].get_position().bounds)

old_pos[-1] /= 2
old_pos2[-2] /= 2
old_pos3[-1] = old_pos3[-2]
old_pos4[-1] /= 2
old_pos4[-2] /= 2

ax[0][0].set_position(old_pos)
ax[1][1].set_position(old_pos2)
ax[1][0].set_position(old_pos3)
ax[0][1].set_position(old_pos4)

# 隐藏多余坐标轴
ax[0][0].xaxis.set_visible(False)
ax[0][1].xaxis.set_visible(False)
ax[1][1].yaxis.set_visible(False)
ax[0][1].yaxis.set_visible(False)

# 适配标题位置
plt.tight_layout(rect=[0, 0, 1, 0.95])
plt.suptitle('Test')

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:24:57