如何使用 gridspec 和 matplotlib 对齐子图轴的高度和宽度?

How to align heights and widths subplot axes with gridspec and matplotlib?

我正在尝试使用 matplotlib with gridspec to create a subplot such that the axes are arranged to look similar to the figure below; the figure was taken from

我尝试重新创建此轴排列的尝试如下。 具体来说,我的问题是轴没有正确对齐。例如,蓝色直方图的轴对象比具有各种绿色阴影的图像的轴对象高;橙色直方图似乎在宽度方面正确对齐,但我将其归因于运气。 如何正确对齐这些轴? 与原始图形不同,我想在轴之间 add/pad 额外留空 space 以使边界不相交;下面代码中的切片符号通过添加空白 row/column 来实现。 (为了不让这个 post 比它必须的更长,我没有通过使用轴刻度等来使数字“漂亮”。)

与原始图片不同,轴没有完全对齐。有没有办法 不用 使用约束布局?通过这个,我的意思是 fig, ax = plt.subplots(constrained_layout=True)?

的一些导数

重新创建我的图形的 MWE 代码如下;请注意 ax.imshow(...)ax.matshow(...).

之间没有区别
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize

## initialize figure and axes
fig = plt.figure()
gs = fig.add_gridspec(6, 6, hspace=0.2, wspace=0.2)
ax_bottom = fig.add_subplot(gs[4:, 2:])
ax_left = fig.add_subplot(gs[:4, :2])
ax_big = fig.add_subplot(gs[:4, 2:])

## generate data
x = np.random.normal(loc=50, scale=10, size=100)
y = np.random.normal(loc=500, scale=50, size=100)

## get singular histograms
x_counts, x_edges = np.histogram(x, bins=np.arange(0, 101, 5))
y_counts, y_edges = np.histogram(y, bins=np.arange(0, 1001, 25))
x_mids = (x_edges[1:] + x_edges[:-1]) / 2
y_mids = (y_edges[1:] + y_edges[:-1]) / 2

## get meshed histogram
sample = np.array([x, y]).T
xy_counts, xy_edges = np.histogramdd(sample, bins=(x_edges, y_edges))

## subplot histogram of x
ax_bottom.bar(x_mids, x_counts,
    width=np.diff(x_edges),
    color='darkorange')
ax_bottom.set_xlim([x_edges[0], x_edges[-1]])
ax_bottom.set_ylim([0, np.max(x_counts)])

## subplot histogram of y
ax_left.bar(y_mids, y_counts,
    width=np.diff(y_edges),
    color='steelblue')
ax_left.set_xlim([y_edges[0], y_edges[-1]])
ax_left.set_ylim([0, np.max(y_counts)])

## subplot histogram of xy-mesh
ax_big.imshow(xy_counts,
    cmap='Greens',
    norm=Normalize(vmin=np.min(xy_counts), vmax=np.max(xy_counts)),
    interpolation='nearest',
    origin='upper')

plt.show()
plt.close(fig)

编辑:

可以通过 row/column 显式设置 width_ratiosheight_ratios 来初始化轴;如下所示。这不会影响输出,但也许我使用不正确?

## initialize figure and axes
fig = plt.figure()
gs = gridspec.GridSpec(ncols=6, nrows=6, figure=fig, width_ratios=[1]*6, height_ratios=[1]*6)
ax_bottom = fig.add_subplot(gs[4:, 2:])
ax_left = fig.add_subplot(gs[:4, :2])
ax_big = fig.add_subplot(gs[:4, 2:])

问题出在 imshow,它会自动调整轴的大小以保持方形像素的外观。 您可以通过调用来阻止这种情况:

ax_big.imshow(..., aspect='auto')