将轴尺寸限制为另一个轴的尺寸

Constrain axis dimensions to those of another axis

我有代码通过使用 GridSpecwidth_ratiosheight_ratios:

import matplotlib.pyplot as plt
import numpy as np

# Some fake data.
imdata = np.random.random((100, 100))
extradata1 = np.max(imdata, axis=1)
extradata2 = np.max(imdata, axis=0)

fig = plt.figure(constrained_layout=True)
spec = fig.add_gridspec(ncols=2, nrows=2, width_ratios=(1, 8), height_ratios=(8, 1))

# Main image plot.
ax1 = fig.add_subplot(spec[:-1, 1:], aspect='equal')
ax1.imshow(imdata, cmap='viridis')

# Vertical (left) plot.
ax2 = fig.add_subplot(spec[:-1, 0], sharey=ax1)
ax2.plot(extradata1, range(imdata.shape[0]))

# Horizontal (bottom) plot.
ax3 = fig.add_subplot(spec[-1, 1:], sharex=ax1)
ax3.plot(range(imdata.shape[1]), extradata2)

plt.show()

我希望左侧绘图的高度和底部绘图的宽度分别等于主图像的高度和宽度。目前,正如您所看到的,水平图比图像的水平尺寸宽,并且随着图形的缩放,它们的缩放比例也不同。是否可以将轴尺寸限制为其他轴的尺寸?

aspect='auto' 调用 imshow() 应该可以解决您的问题:

ax1.imshow(imdata, cmap='viridis',aspect='auto')

关于这方面的更多解释,请看这里: Imshow: extent and aspect

import matplotlib.pyplot as plt
import numpy as np

# Some fake data.
imdata = np.random.random((100, 100))
extradata1 = np.max(imdata, axis=1)
extradata2 = np.max(imdata, axis=0)

fig = plt.figure(constrained_layout=True)
spec = fig.add_gridspec(ncols=2, nrows=2, width_ratios=(1, 8), height_ratios=(8, 1))

# Main image plot.
ax1 = fig.add_subplot(spec[:-1, 1:])
ax1.imshow(imdata, cmap='viridis',aspect='auto')

# Vertical (left) plot.
ax2 = fig.add_subplot(spec[:-1, 0], sharey=ax1)
ax2.plot(extradata1, range(imdata.shape[0]))

# Horizontal (bottom) plot.
ax3 = fig.add_subplot(spec[-1, 1:], sharex=ax1)
ax3.plot(range(imdata.shape[1]), extradata2)

结果:

工作得很好,但我还发现我可以通过在 plt.figure 调用中将 constrained_layout=True 更改为 constrained_layout=False 来获得所需的行为。

使用纵横比 aspect="auto" 是可行的,但它的缺点是给你非正方形像素。

对于这类任务,我发现 the axes_grid toolkit 非常有用

from mpl_toolkits.axes_grid1 import make_axes_locatable

# Some fake data.
imdata = np.random.random((100, 100))
extradata1 = np.max(imdata, axis=1)
extradata2 = np.max(imdata, axis=0)

fig, main_ax = plt.subplots()
divider = make_axes_locatable(main_ax)
bottom_ax = divider.append_axes("bottom", 1.2, pad=0.1, sharex=main_ax)
left_ax = divider.append_axes("left", 1.2, pad=0.1, sharey=main_ax)

bottom_ax.xaxis.set_tick_params(labelbottom=False)
left_ax.yaxis.set_tick_params(labelleft=False)


main_ax.imshow(imdata, cmap='viridis')
left_ax.plot(extradata1, range(imdata.shape[0]))
bottom_ax.plot(range(imdata.shape[1]), extradata2)

plt.show()