Figure 内に複数の Axes を配置する#

一度に複数の Axes が必要になることがよくあり、通常は通常のグリッドに編成されます。Matplotlib には、ライブラリの歴史の中で進化してきた Axes のグリッドを操作するためのさまざまなツールがあります。ここでは、ユーザーが最も頻繁に使用する必要があると思われるツール、Axes の編成方法を支えるツールについて説明し、いくつかの古いツールについて言及します。

ノート

Matplotlib はAxesを使用して、データ、x 軸と y 軸、目盛り、ラベル、タイトルなどを含む描画領域を参照します。詳細については、Figure のパーツを参照 してください。よく使用される別の用語は「サブプロット」です。これは、他の Axes オブジェクトを含むグリッド内にある Axes を指します。

概要#

軸の格子状の組み合わせを作成する#

subplots

Figure と Axes のグリッドを作成するために使用される主要な関数。一度にすべての Axes を作成して Figure に配置し、グリッド内の Axes のハンドルを含むオブジェクト配列を返します。を参照してください Figure.subplots

また

subplot_mosaic

図と Axes のグリッドを作成する簡単な方法で、Axes が行または列にまたがることができる柔軟性が追加されています。Axes は、配列ではなく、ラベル付きのディクショナリで返されます。複雑でセマンティックな図の構成も参照して Figure.subplot_mosaicください。

Axes グリッドの複数の異なるグループを持つことが自然な場合があります。その場合、Matplotlib には次の概念がありSubFigureます。

SubFigure

フィギュアの中の仮想フィギュア。

基礎となるツール#

これらの根底にあるのは、 aGridSpecおよび aの概念SubplotSpecです。

GridSpec

サブプロットが配置されるグリッドのジオメトリを指定します。グリッドの行数と列数を設定する必要があります。必要に応じて、サブプロット レイアウト パラメーター (左、右など) を調整できます。

SubplotSpec

指定された 内のサブプロットの場所を指定しますGridSpec

一度に単一の軸を追加する#

上記の関数は、1 回の関数呼び出しですべての Axes を作成します。Axes を一度に 1 つずつ追加することもできます。これは、もともと Matplotlib が機能していた方法です。これを行うと、一般的にエレガントで柔軟性が低下しますが、インタラクティブな作業や、Axes をカスタムの場所に配置する場合に便利な場合があります。

add_axes

Figure の幅または高さの分数で指定された位置に単一の軸を追加します 。[left, bottom, width, height]

subplotまたFigure.add_subplot

1 ベースのインデックス (Matlab から継承) を使用して、Figure に単一のサブプロットを追加します。グリッド セルの範囲を指定することで、列と行をまたがることができます。

subplot2grid

に似てpyplot.subplotいますが、0 ベースのインデックスと 2 次元の python スライスを使用してセルを選択します。

グリッドを作成するための高レベルのメソッド#

基本的な 2x2 グリッド#

を使用して、Axes の基本的な 2 行 2 列のグリッドを作成できます subplotsFigure インスタンスとオブジェクトの配列を返しAxesます。Axes オブジェクトを使用して、Axes にアーティストを配置するメソッドにアクセスできます。ここでは を使用していますannotateが、他の例plotとして pcolormesh、 などがあります。

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(ncols=2, nrows=2, figsize=(5.5, 3.5),
                        layout="constrained")
# add an artist, in this case a nice label in the middle...
for row in range(2):
    for col in range(2):
        axs[row, col].annotate(f'axs[{row}, {col}]', (0.5, 0.5),
                               transform=axs[row, col].transAxes,
                               ha='center', va='center', fontsize=18,
                               color='darkgrey')
fig.suptitle('plt.subplots()')
plt.subplots()
Text(0.5, 0.9880942857142857, 'plt.subplots()')

多くの Axes に注釈を付けるので、必要なたびに注釈コードの大部分を用意するのではなく、注釈をカプセル化しましょう。

def annotate_axes(ax, text, fontsize=18):
    ax.text(0.5, 0.5, text, transform=ax.transAxes,
            ha="center", va="center", fontsize=fontsize, color="darkgrey")

を使用しても同じ効果が得られますsubplot_mosaicが、戻り値の型は配列ではなく辞書であり、ユーザーはキーに有用な意味を与えることができます。ここでは、2 つのリストを提供します。各リストは行を表し、リスト内の各要素は列を表すキーです。

fig, axd = plt.subplot_mosaic([['upper left', 'upper right'],
                               ['lower left', 'lower right']],
                              figsize=(5.5, 3.5), layout="constrained")
for k in axd:
    annotate_axes(axd[k], f'axd["{k}"]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')
plt.subplot_mosaic()
Text(0.5, 0.9880942857142857, 'plt.subplot_mosaic()')

固定縦横比のグリッド

固定縦横比の軸は、イメージまたはマップで一般的です。ただし、Axes のサイズには、Axes が Figure に収まることと、設定された縦横比があることの 2 つの制約があるため、レイアウトに課題が生じます。これにより、デフォルトで軸間に大きなギャップが生じます。

fig, axs = plt.subplots(2, 2, layout="constrained", figsize=(5.5, 3.5))
for ax in axs.flat:
    ax.set_aspect(1)
fig.suptitle('Fixed aspect Axes')
固定アスペクト軸
Text(0.5, 0.9880942857142857, 'Fixed aspect Axes')

これに対処する 1 つの方法は、Axes の縦横比に近くなるように Figure の縦横比を変更することですが、これには試行錯誤が必要です。Matplotlib はlayout="compressed"、単純なグリッドで動作して軸間のギャップを減らす も提供します。(mpl_toolkitsImageGrid同様の効果を実現しますが、非標準の Axes クラスを使用します)。

fig, axs = plt.subplots(2, 2, layout="compressed", figsize=(5.5, 3.5))
for ax in axs.flat:
    ax.set_aspect(1)
fig.suptitle('Fixed aspect Axes: compressed')
固定アスペクト 軸: 圧縮
Text(0.5, 0.9880942857142857, 'Fixed aspect Axes: compressed')

グリッド内の行または列にまたがる軸#

Axes をグリッドの行または列にまたがらせたい場合があります。これを実現する方法は実際には複数ありますが、おそらく最も便利なのはsubplot_mosaic、キーの 1 つを繰り返し使用することです。

fig, axd = plt.subplot_mosaic([['upper left', 'right'],
                               ['lower left', 'right']],
                              figsize=(5.5, 3.5), layout="constrained")
for k in axd:
    annotate_axes(axd[k], f'axd["{k}"]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')
plt.subplot_mosaic()
Text(0.5, 0.9880942857142857, 'plt.subplot_mosaic()')

GridSpecまたはを使用して同じことを行う方法の説明については、以下を参照してください subplot2grid

グリッド内の可変幅または高さ#

と の両方subplotsで、 gridspec_kwキーワード引数subplot_mosaicを使用して、グリッド内の行を異なる高さにし、列を異なる幅にすることができます。によって受け入れられるスペーシング パラメータは、および に渡すことができます。GridSpecsubplotssubplot_mosaic

gs_kw = dict(width_ratios=[1.4, 1], height_ratios=[1, 2])
fig, axd = plt.subplot_mosaic([['upper left', 'right'],
                               ['lower left', 'right']],
                              gridspec_kw=gs_kw, figsize=(5.5, 3.5),
                              layout="constrained")
for k in axd:
    annotate_axes(axd[k], f'axd["{k}"]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')
plt.subplot_mosaic()
Text(0.5, 0.9880942857142857, 'plt.subplot_mosaic()')

ネストされた軸のレイアウト#

相互に関連付ける必要のない 2 つ以上の Axes グリッドがあると便利な場合があります。これを実現する最も簡単な方法は、 を使用することFigure.subfiguresです。サブフィギュアのレイアウトは独立しているため、各サブフィギュアの軸スパインは必ずしも整列していないことに注意してください。で同じ効果を達成するためのより詳細な方法については、以下を参照してくださいGridSpecFromSubplotSpec

fig = plt.figure(layout="constrained")
subfigs = fig.subfigures(1, 2, wspace=0.07, width_ratios=[1.5, 1.])
axs0 = subfigs[0].subplots(2, 2)
subfigs[0].set_facecolor('0.9')
subfigs[0].suptitle('subfigs[0]\nLeft side')
subfigs[0].supxlabel('xlabel for subfigs[0]')

axs1 = subfigs[1].subplots(3, 1)
subfigs[1].suptitle('subfigs[1]')
subfigs[1].supylabel('ylabel for subfigs[1]')
軸の配置
Text(0.016867713730569944, 0.5, 'ylabel for subfigs[1]')

ネストされたリストを使用して、Axes をネストすることもできsubplot_mosaicます。このメソッドは、上記のようにサブフィギュアを使用しないため、サブフィギュアごとにsuptitlesupxlabelなどを追加する機能がありません。むしろ、subgridspec 以下で説明するメソッドの便利なラッパーです。

inner = [['innerA'],
         ['innerB']]
outer = [['upper left',  inner],
          ['lower left', 'lower right']]

fig, axd = plt.subplot_mosaic(outer, layout="constrained")
for k in axd:
    annotate_axes(axd[k], f'axd["{k}"]')
軸の配置

低レベルおよび高度なグリッド メソッド#

内部的には、Axes のグリッドの配置は、 と のインスタンスを作成することによって制御されGridSpecますSubplotSpecGridSpecは、セルの (不均一な) グリッドを定義します。GridSpec にインデックスを付けると、1 つ以上のグリッド セルをカバーするSubplotSpecが返され、Axes の位置を指定するために使用できます。

次の例は、低レベルのメソッドを使用して、GridSpecオブジェクトを使用して Axes を配置する方法を示しています。

基本的な 2x2 グリッド#

と同じ方法で 2x2 グリッドを実現できます 。plt.subplots(2, 2)

fig = plt.figure(figsize=(5.5, 3.5), layout="constrained")
spec = fig.add_gridspec(ncols=2, nrows=2)

ax0 = fig.add_subplot(spec[0, 0])
annotate_axes(ax0, 'ax0')

ax1 = fig.add_subplot(spec[0, 1])
annotate_axes(ax1, 'ax1')

ax2 = fig.add_subplot(spec[1, 0])
annotate_axes(ax2, 'ax2')

ax3 = fig.add_subplot(spec[1, 1])
annotate_axes(ax3, 'ax3')

fig.suptitle('Manually added subplots using add_gridspec')
add_gridspec を使用して手動で追加されたサブプロット
Text(0.5, 0.9880942857142857, 'Manually added subplots using add_gridspec')

グリッド内の行またはグリッドにまたがる軸#

NumPy スライス構文を使用して仕様配列にインデックスを付けることができ 、新しい Axes はスライスにまたがります。これは次と同じです:fig, axd = plt.subplot_mosaic([['ax0', 'ax0'], ['ax1', 'ax2']], ...)

fig = plt.figure(figsize=(5.5, 3.5), layout="constrained")
spec = fig.add_gridspec(2, 2)

ax0 = fig.add_subplot(spec[0, :])
annotate_axes(ax0, 'ax0')

ax10 = fig.add_subplot(spec[1, 0])
annotate_axes(ax10, 'ax10')

ax11 = fig.add_subplot(spec[1, 1])
annotate_axes(ax11, 'ax11')

fig.suptitle('Manually added subplots, spanning a column')
列にまたがる手動で追加されたサブプロット
Text(0.5, 0.9880942857142857, 'Manually added subplots, spanning a column')

GridSpecレイアウトの手動調整#

GridSpecを明示的に使用すると、GridSpecから作成されたサブプロットのレイアウト パラメーターを調整できます。このオプションは、を無視し、サブプロットのサイズを調整して Figure を埋める と互換constrained_layout性 がないことに注意してください。通常、このような手動配置では、Axes の目盛りラベルが Axes と重ならないようにするための反復が必要です。Figure.tight_layout

これらの間隔パラメータは、 gridspec_kw引数として渡すこともできsubplotsます 。subplot_mosaic

fig = plt.figure(layout=None, facecolor='0.9')
gs = fig.add_gridspec(nrows=3, ncols=3, left=0.05, right=0.75,
                      hspace=0.1, wspace=0.05)
ax0 = fig.add_subplot(gs[:-1, :])
annotate_axes(ax0, 'ax0')
ax1 = fig.add_subplot(gs[-1, :-1])
annotate_axes(ax1, 'ax1')
ax2 = fig.add_subplot(gs[-1, -1])
annotate_axes(ax2, 'ax2')
fig.suptitle('Manual gridspec with right=0.75')
right=0.75 の手動グリッドスペック
Text(0.5, 0.98, 'Manual gridspec with right=0.75')

SubplotSpec を使用したネストされたレイアウト#

subfiguresを使用 する場合と同様に、ネストされたレイアウトを作成できますsubgridspec。ここでは、Axes スパイン 整列しています。

これは more verbose からも利用できることに注意してください gridspec.GridSpecFromSubplotSpec

fig = plt.figure(layout="constrained")
gs0 = fig.add_gridspec(1, 2)

gs00 = gs0[0].subgridspec(2, 2)
gs01 = gs0[1].subgridspec(3, 1)

for a in range(2):
    for b in range(2):
        ax = fig.add_subplot(gs00[a, b])
        annotate_axes(ax, f'axLeft[{a}, {b}]', fontsize=10)
        if a == 1 and b == 1:
            ax.set_xlabel('xlabel')
for a in range(3):
    ax = fig.add_subplot(gs01[a])
    annotate_axes(ax, f'axRight[{a}, {b}]')
    if a == 2:
        ax.set_ylabel('ylabel')

fig.suptitle('nested gridspecs')
ネストされたグリッドスペック
Text(0.5, 0.99131875, 'nested gridspecs')

ネストされたGridSpecのより洗練された例を次に示します。各セルに Axes の内側の 3x3 グリッドを含む外側の 4x4 グリッドを作成します。内側の 3x3 グリッドのそれぞれで適切なスパインを非表示にして、外側の 4x4 グリッドの輪郭を描きます。

def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)):
    return np.sin(i*a)*np.cos(i*b), np.sin(i*c)*np.cos(i*d)

fig = plt.figure(figsize=(8, 8), constrained_layout=False)
outer_grid = fig.add_gridspec(4, 4, wspace=0, hspace=0)

for a in range(4):
    for b in range(4):
        # gridspec inside gridspec
        inner_grid = outer_grid[a, b].subgridspec(3, 3, wspace=0, hspace=0)
        axs = inner_grid.subplots()  # Create all subplots for the inner grid.
        for (c, d), ax in np.ndenumerate(axs):
            ax.plot(*squiggle_xy(a + 1, b + 1, c + 1, d + 1))
            ax.set(xticks=[], yticks=[])

# show only the outside spines
for ax in fig.get_axes():
    ss = ax.get_subplotspec()
    ax.spines.top.set_visible(ss.is_first_row())
    ax.spines.bottom.set_visible(ss.is_last_row())
    ax.spines.left.set_visible(ss.is_first_col())
    ax.spines.right.set_visible(ss.is_last_col())

plt.show()
軸の配置

もっと読む#

スクリプトの合計実行時間: ( 0 分 13.006 秒)

Sphinx-Gallery によって生成されたギャラリー