HOWTO · Matplotlib

Matplotlib で 1つの図に複数の画像を正しく表示する方法

軸のグリッドを使用して 1 つの Matplotlib の図に複数の画像を表示し、個々のパネルをカスタマイズします。

このページの内容

1 つの図に複数の画像を表示するには、画像ごとに 1 つの軸を持つ Matplotlib の図を作成し、対応する軸で imshow() を呼び出します。fig.add_subplot() を使うとループでグリッドを構築できます。軸を配列として取得したい場合は plt.subplots() が便利です。

Matplotlib の add_subplot() を for ループで使用する

行数、列数、および 1 から始まるパネルのインデックスを fig.add_subplot(rows, columns, index) に渡します。以下のループは、2 行 2 列のグリッドを 4 つの異なる配列で埋め、各パネルにタイトルを付けます。これらの例はここでは実行されません。説明は、示されているコードと API の使用法を述べています。

この例を実行します。

import numpy as np
import matplotlib.pyplot as plt

rows, cols = 2, 2
images = [np.full((8, 8), value) for value in (1, 2, 3, 4)]
fig = plt.figure(figsize=(6, 5))

for index, image in enumerate(images, start=1):
    ax = fig.add_subplot(rows, cols, index)
    ax.imshow(image, cmap="viridis")
    ax.set_title(f"Image {index}")

fig.tight_layout()
plt.show()

各イテレーションは 1 つの軸を作成し、そのイテレーションの画像をそこに表示します。後で個々のパネルをカスタマイズしたい場合は、返された軸を保持してください。規則的なグリッドについては、plt.subplots() は軸を行と列の形式で返します。イテレーションのためにそれらを平坦化し、特定のパネルを選択するには 2 つのインデックスを使用します。

import numpy as np
import matplotlib.pyplot as plt

rows, cols = 2, 2
images = [np.full((8, 8), value) for value in (1, 2, 3, 4)]
x = np.linspace(0, 7, 8)
fig, axes = plt.subplots(rows, cols, figsize=(6, 5))

for index, (ax, image) in enumerate(zip(axes.flat, images), start=1):
    ax.imshow(image, cmap="viridis", alpha=0.75)
    ax.set_title(f"Image {index}")

axes[0, 1].plot(x, x, color="white")
axes[1, 1].plot(x, 7 - x, color="red")
fig.tight_layout()
plt.show()

ここで axes.flat は各パネルをたどる簡単な方法を提供し、axes[row, column] は特定のパネルを指定します。追加の線は、それらのパネルの画像の上に描画されます。グリッドにすべての画像に対する十分な軸があることを確認してください。zip() はどちらかの入力が尽きると停止するため、対応しない画像や軸はそのループでは表示されません。

Matplotlib のサブプロットに基づく関数を定義する

繰り返し使用するために、グリッドの設定を関数にまとめます。このバージョンは軸を平坦な配列に変換するため、1 行 1 列のグリッドも処理し、グリッドにすべての画像の余地があることを確認し、各パネルにタイトルを付け、画像中心の図のために軸を非表示にします。

import numpy as np
import matplotlib.pyplot as plt


def display_multiple_img(images, rows=1, cols=1):
    images = list(images.items())
    figure, axes = plt.subplots(nrows=rows, ncols=cols)
    axes = np.atleast_1d(axes).ravel()

    if len(images) > len(axes):
        raise ValueError("The grid must have at least one axis per image.")

    for ax, (title, image) in zip(axes, images):
        ax.imshow(image, cmap="viridis")
        ax.set_title(title)
        ax.set_axis_off()

    for ax in axes[len(images):]:
        ax.set_axis_off()

    figure.tight_layout()
    plt.show()


images = {
    "Image 1": np.full((8, 8), 1),
    "Image 2": np.full((8, 8), 2),
    "Image 3": np.full((8, 8), 3),
    "Image 4": np.full((8, 8), 4),
}
display_multiple_img(images, rows=2, cols=2)

タイトルから画像配列への挿入順のマッピングと、希望するグリッドの寸法を渡します。この関数はイテレーションの前に軸を平坦なシーケンスに変えるため、単一のパネルでも複数パネルのグリッドでも同様に機能します。利用可能な軸より画像が多い場合、ValueError が発生します。すべてを表示するには rows または cols を増やしてください。