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

Matplotlib共享轴子图设置单图轴比例问题求助

Matplotlib共享轴子图的轴比例设置解决方案

我有一个2×2的Matplotlib子图布局,其中三个子图共享轴:顶部直方图(ax[0,0])、右侧直方图(ax[1,1])和中心二维直方图(ax[1,0])。想要为中心的二维直方图设置等轴比例,但尝试使用box_aspect的方法后,要么只影响单个子图,要么打乱整体布局。

原代码(补全缺失的numpy导入):

import matplotlib.pyplot as plt
from scipy.stats import norm
import numpy as np

fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(12, 8),
                       gridspec_kw={'width_ratios': [3, 1],
                                    'height_ratios': [1, 3],
                                    'wspace': 0.0,
                                    'hspace': 0.0},
                       sharex='col', sharey='row', 
                       subplot_kw=(dict(box_aspect=1) if False else None)) # 启用后布局混乱

x, y = norm.rvs(size=10000), norm.rvs(size=10000)

ax[0][0].hist(x, bins=30)
ax[1][1].hist(y, bins=30, orientation='horizontal')
ax[1][0].hist2d(x, y, bins=[np.linspace(-4, 4, 30), np.linspace(-4, 4, 30)])

plt.show()

问题根源

sharex='col'和sharey='row'会强制同列/同行的子图轴范围和尺寸同步,而box_aspect或set_aspect('equal')会修改子图的宽高比例,两者冲突导致布局错乱。

解决方案1:调整布局比例适配等轴要求

通过修改figsize和gridspec的比例,让中心子图的原生宽高相等,再设置等轴比例,避免冲突:

import matplotlib.pyplot as plt
from scipy.stats import norm
import numpy as np

# 设为正方形画布,配合gridspec比例让中心子图宽高相等
fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(10, 10),
                       gridspec_kw={'width_ratios': [3, 1],
                                    'height_ratios': [1, 3],
                                    'wspace': 0.0,
                                    'hspace': 0.0},
                       sharex='col', sharey='row')

x, y = norm.rvs(size=10000), norm.rvs(size=10000)
x_bins = np.linspace(-4, 4, 30)
y_bins = np.linspace(-4, 4, 30)

ax[0][0].hist(x, bins=x_bins)
ax[1][1].hist(y, bins=y_bins, orientation='horizontal')
ax[1][0].hist2d(x, y, bins=[x_bins, y_bins])

# 为中心子图设置等轴比例,此时宽高原生相等,不会挤压其他子图
ax[1,0].set_aspect('equal', adjustable='box')

plt.show()

解决方案2:手动同步轴范围,放弃自动共享

不依赖Matplotlib的sharex/sharey,手动同步轴范围并隐藏多余刻度,自由设置中心子图比例:

import matplotlib.pyplot as plt
from scipy.stats import norm
import numpy as np

fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(12, 8),
                       gridspec_kw={'width_ratios': [3, 1],
                                    'height_ratios': [1, 3],
                                    'wspace': 0.0,
                                    'hspace': 0.0})

x, y = norm.rvs(size=10000), norm.rvs(size=10000)
x_bins = np.linspace(-4, 4, 30)
y_bins = np.linspace(-4, 4, 30)

ax[0][0].hist(x, bins=x_bins)
ax[1][1].hist(y, bins=y_bins, orientation='horizontal')
ax[1][0].hist2d(x, y, bins=[x_bins, y_bins])

# 手动同步所有子图的轴范围
x_min, x_max = x_bins.min(), x_bins.max()
y_min, y_max = y_bins.min(), y_bins.max()
ax[0,0].set_xlim(x_min, x_max)
ax[1,0].set_xlim(x_min, x_max)
ax[1,0].set_ylim(y_min, y_max)
ax[1,1].set_ylim(y_min, y_max)

# 隐藏多余刻度,模拟共享轴的视觉效果
ax[0,0].tick_params(axis='x', labelbottom=False)
ax[1,1].tick_params(axis='y', labelleft=False)

# 自由设置中心子图的等轴比例,不影响其他子图
ax[1,0].set_aspect('equal')

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:30:57