【问题标题】:Matplotlib: Shared axis for imshow imagesMatplotlib:imshow 图像的共享轴
【发布时间】:2020-07-07 19:07:13
【问题描述】:

我正在尝试使用 Matplotlib 的 imshow() 方法绘制多个图像,并让它们共享一个 y 轴。尽管图像具有相同数量的 y 像素,但图像的高度不同。

演示代码;


import numpy as np
import matplotlib.pyplot as plt

from scipy.stats import poisson


def ibp_oneparam(alpha, N):
    """One-parameter IBP"""

    # First customer
    Z = np.array([np.ones(poisson(alpha).rvs(1))], dtype=int)

    # ith customer
    for i in range(2, N+1):

        # Customer walks along previously sampled dishes
        z_i = []
        for previously_sampled_dish in Z.T:
            m_k = np.sum(previously_sampled_dish)
            if np.random.rand() >= m_k / i:
                # Customer decides to sample this dish
                z_i.append(1.0)
            else:
                # Customer decides to skip this dish
                z_i.append(0.0)

        # Customer decides to try some new dishes
        z_i.extend(np.ones(poisson(alpha / i).rvs(1)))
        z_i = np.array(z_i)

        # Add this customer to Z
        Z_new = np.zeros((
            Z.shape[0] + 1,
            max(Z.shape[1], len(z_i))
        ))
        Z_new[0:Z.shape[0], 0:Z.shape[1]] = Z
        Z = Z_new
        Z[i-1, :] = z_i

    return Z


np.random.seed(3)

N = 10
alpha = 2.0

#plt.figure(dpi=100)
fig, (ax1, ax2, ax3) = plt.subplots(
    1,
    3,
    dpi=100,
    sharey=True
)

Z = ibp_oneparam(alpha, N)
plt.sca(ax1)
plt.imshow(
    Z,
    extent=(0.5, Z.shape[1] + 0.5, len(Z) + 0.5, 0.5),
    cmap='Greys_r'
)
plt.ylabel("Customers")
plt.xlabel("Dishes")
plt.xticks(range(1, Z.shape[1] + 1))
plt.yticks(range(1, Z.shape[0] + 1))

Z = ibp_oneparam(alpha, N)
plt.sca(ax2)
plt.imshow(
    Z,
    extent=(0.5, Z.shape[1] + 0.5, len(Z) + 0.5, 0.5),
    cmap='Greys_r'
)
plt.xlabel("Dishes")
plt.xticks(range(1, Z.shape[1] + 1))

Z = ibp_oneparam(alpha, N)
plt.sca(ax3)
plt.imshow(
    Z,
    extent=(0.5, Z.shape[1] + 0.5, len(Z) + 0.5, 0.5),
    cmap='Greys_r'
)
plt.xlabel("Dishes")
plt.xticks(range(1, Z.shape[1] + 1))

plt.show()

输出;

我希望这些图像每个都具有相同的高度,并且具有不同的宽度。我怎样才能做到这一点?

旁白:上面的代码演示了Indian Buffet Process。出于本文的目的,将三个图像视为具有相同行数但列数可变的随机二进制矩阵。

谢谢,

【问题讨论】:

    标签: python matplotlib plot imshow


    【解决方案1】:

    我使用 grid-spec width_ratios 得到了不错的结果。

    """fig, (ax1, ax2, ax3) = plt.subplots(
        1,
        3,
        dpi=100,
        sharey=True,
        constrained_layout=True
    )"""
    

    # I commented the above code and replaced with below.

    import matplotlib.gridspec as gridspec
    fig = plt.figure(constrained_layout=True)
    gs = gridspec.GridSpec(ncols=3, nrows=1, figure=fig, width_ratios=[7./4.,1,6./4.])
    ax1 = fig.add_subplot(gs[0,0])
    ax2 = fig.add_subplot(gs[0,1])
    ax3 = fig.add_subplot(gs[0,2])
    

    您需要使用宽度比来调整高度,这有点违反直觉,但在具有多行的网格的上下文中,您只能按宽度独立缩放列是有道理的。并按高度独立行。 https://matplotlib.org/tutorials/intermediate/gridspec.html

    【讨论】:

    • 谢谢 - 这似乎是解决这个问题的正确方法。在一般情况下,我的图像的宽度可能是可变的,所以我只需要预先计算每个图像,以便在构建子图之前知道宽度。
    猜你喜欢
    • 1970-01-01
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    • 2023-03-14
    • 1970-01-01
    相关资源
    最近更新 更多