如何绘制 2D 图像并将其投影与轴对齐,使绘图尺寸与图像相比较小?

How can I plot a 2D image and align its projection to the axes keeping the plots dimension small compared to the image?

提问人:G M 提问时间:11/17/2023 更新时间:11/17/2023 访问量:44

问:

我正在努力寻找一种方法来保持图像的投影与图像完全对齐(如下图所示),但同时减小它们的尺寸,使图像占据大部分图形空间。

    import matplotlib.pyplot as plt
    import matplotlib.gridspec as gridspec
    import matplotlib.image as mpimg
    import numpy as np
    from skimage import data
    img = data.coins()
    h,w = img.shape
    ratio = h/w
    fig = plt.figure(figsize=(8, 8))
    gs = gridspec.GridSpec(2, 2, width_ratios=[1*ratio, 1], height_ratios=[1/ratio, 1])
    ax_center = plt.subplot(gs[1, 1])
    ax_center.imshow(img)
    ax_left = plt.subplot(gs[1, 0])
    ax_left.set_title('Left Plot')
    ax_left.plot(-img.mean(axis=1),range(img.shape[0]))
    ax_top = plt.subplot(gs[0, 1])
    ax_top.plot(img.mean(axis=0))
    ax_top.set_title('Top Plot')
    plt.tight_layout()
    plt.show()

enter image description here

基本上,我希望顶部图的高度较小,而左侧顶部的宽度较小,使它们与图像完美对齐。

蟒蛇 matplotlib-gridspec

评论


答:

2赞 Matt Pitkin 11/17/2023 #1

您可以执行以下操作(通过设置 aspect=“auto”,图像可能会失真,因此在下面的示例中,我适当地调整了图形大小以考虑这一点):

from matplotlib import pyplot as plt
from skimage import data
import numpy as np


img = np.flipud(data.coins())

shape = img.shape
fwidth = 8  # set figure width
fheight = fwidth * (shape[0] / shape[1])  # set figure height

fig, ax = plt.subplots(
    2,
    2,
    sharex="col",
    sharey="row",
    width_ratios=[0.2, 1],  # set left subplot to be 20% width of image
    height_ratios=[0.2, 1],  # set top subplot to be 20% height of image
    figsize=[fwidth + 0.2 * fheight, fheight + 0.2 * fwidth],
)

# you need aspect="auto" to make sure axes align (although this will distort the image!)
ax[1, 1].imshow(img, aspect="auto")

ax[1, 0].plot(-img.mean(axis=1), range(img.shape[0]))
ax[1, 0].set_title('Left Plot')

ax[0, 1].plot(img.mean(axis=0))
ax[0, 1].set_title('Top Plot')

ax[1, 1].set_xlim([0, img.shape[1] - 1])
ax[1, 1].set_ylim([0, img.shape[0] - 1])

ax[0, 0].axis("off")

fig.tight_layout()
plt.show()

这会产生:

enter image description here

评论

0赞 G M 11/17/2023
非常感谢 +1,似乎它在 matplotlib 3.5 中不起作用,我可能应该使用 3.6
0赞 Matt Pitkin 11/17/2023
是的,我使用的是 v3.6.3
0赞 G M 11/17/2023
唯一的问题是图像是颠倒的
0赞 G M 11/17/2023
我会补充plt.gca().invert_yaxis()
0赞 Matt Pitkin 11/17/2023
我已经编辑了它以使用np.flipud