Matplotlib: общая ось для изображений imshow - PullRequest
0 голосов
/ 27 марта 2020

Я пытаюсь построить несколько изображений с помощью метода imshow() Matplotlib, чтобы они разделяли одну ось 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()

Вывод;

Three subplots each showing a binary image

Я ожидаю, что эти изображения будут иметь одинаковую высоту и разную ширину. Как мне этого добиться?

В сторону: Приведенный выше код демонстрирует Индийский процесс шведского стола . Для целей этого поста рассмотрим три изображения как случайные двоичные матрицы с одинаковым количеством строк, но с переменным числом столбцов.

Спасибо,

1 Ответ

1 голос
/ 27 марта 2020

Я получил приличный результат с grid-spe c width_rat ios.

"""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])

Resulting

Немного интуитивно понятно, что вам нужно использовать width rat ios для регулировки высоты, но в контексте сетки с несколькими строками имеет смысл, что вы можете масштабировать столбцы независимо только по ширине. и ряды независимо по высоте. https://matplotlib.org/tutorials/intermediate/gridspec.html

...