Matplotlib サブプロットの作成

MatplotlibBeginner
オンラインで実践に進む

はじめに

データ可視化において、1 つの図に複数のプロットを表示することはしばしば有用です。これにより、異なるデータセット間や、同じデータの異なるビュー間での比較が容易になります。Matplotlib は、サブプロットを使用してこのような図を作成するための強力で便利な方法を提供します。

サブプロットを作成する最も一般的な方法は、plt.subplots()関数を使用することです。この関数は、1 回の呼び出しで図とサブプロットのグリッドを作成し、Figureオブジェクトと、各個々のサブプロットを表すAxesオブジェクトの配列を返します。

この実験(Lab)では、以下の方法を学びます。

  • 複数のサブプロットを含む図の作成
  • 特定のサブプロットへのデータのプロット
  • プロットが重ならないようにレイアウトを調整
  • より明確な比較のためにサブプロット間で軸を共有

WebIDE で Python スクリプトを作成し、実行します。この環境はインタラクティブな GUI ウィンドウをサポートしていないため、プロットを画像ファイルとして保存し、エディタで直接表示します。

plt.subplots() を使用して図と軸を作成する

このステップでは、1 行 2 列に配置された 2 つの空のサブプロットを含む図を作成することから始めます。これは、複数プロットの可視化を構築するための基本的なステップです。

plt.subplots() 関数を使用します。plt.subplots(nrows, ncols) を呼び出すと、2 つの項目が返されます。

  1. Figure オブジェクト:これは、すべてが描画される全体的なウィンドウまたはページです。通常、fig という名前の変数に割り当てます。
  2. Axes オブジェクトの配列:各 Axes オブジェクトは、グリッド内の 1 つのサブプロットを表します。インデックスでアクセスできます。(1, 2) のグリッドの場合、この配列を ax1ax2 の 2 つの変数にアンパックできます。

コードを記述しましょう。左側のファイルエクスプローラーから main.py ファイルを開き、以下の内容を追加します。このスクリプトは、必要なライブラリをインポートし、2 つのサブプロットを持つ図を作成し、plot1.png という名前の画像ファイルとして保存します。

import matplotlib.pyplot as plt
import numpy as np

## 図とサブプロットのセットを作成します。
## 1 行、2 列。
fig, (ax1, ax2) = plt.subplots(1, 2)

## 図をファイルに保存します。
## ファイルは /home/labex/project ディレクトリに作成されます。
plt.savefig('plot1.png')

print("Figure saved as plot1.png")

次に、ターミナルからスクリプトを実行してプロットを生成します。

python3 main.py

ターミナルに以下の出力が表示されるはずです。

Figure saved as plot1.png

plot1.png という新しいファイルがファイルエクスプローラーに表示されます。それをダブルクリックすると、2 つの空のサブプロットを持つ最初の図が表示されます。

Plot1

ax1.plot() を使用して最初のサブプロットにプロットする

このステップでは、作成した特定の Axes オブジェクトのいずれかにプロットを描画する方法を学びます。各 Axes オブジェクトには、メインの plt インターフェースの関数と同様に、plot()bar()scatter() などの独自のプロットメソッドがあります。

最初のサブプロット(ax1 変数で表される)に単純なサイン波をプロットします。また、set_title() メソッドを使用して、このサブプロットにタイトルを追加します。

main.py ファイルを以下のコードで更新してください。NumPy を使用したデータ生成を追加し、それを ax1 にプロットします。

import matplotlib.pyplot as plt
import numpy as np

## データの作成
x = np.linspace(0, 2 * np.pi, 400)
y = np.sin(x ** 2)

## 図とサブプロットのセットを作成します
fig, (ax1, ax2) = plt.subplots(1, 2)

## 最初のサブプロット (ax1) にプロットします
ax1.plot(x, y)
ax1.set_title('Sine Wave')

## 図を新しいファイルに保存します
plt.savefig('plot2.png')

print("Figure saved as plot2.png")

次に、ターミナルで更新されたスクリプトを実行します。

python3 main.py

以下の出力が表示されます。

Figure saved as plot2.png

plot2.png という新しいファイルがプロジェクトディレクトリに作成されました。それを開いて結果を確認してください。左側のサブプロットにはサイン波のプロットが表示され、右側のサブプロットは空のままになっているはずです。

Plot2

ax2.plot() を使用して 2 番目のサブプロットにプロットする

このステップでは、2 番目のサブプロットにプロットを追加して図を完成させます。プロセスは前のステップと同じですが、今回は ax2 オブジェクトに対して plot() メソッドを呼び出します。

サイン波と比較するために、2 番目のサブプロットにコサイン波をプロットします。タイトルも付けます。

main.py ファイルを編集して、2 番目の軸へのプロットを含めます。

import matplotlib.pyplot as plt
import numpy as np

## データの作成
x = np.linspace(0, 2 * np.pi, 400)
y1 = np.sin(x ** 2)
y2 = np.cos(x ** 2)

## 図とサブプロットのセットを作成します
fig, (ax1, ax2) = plt.subplots(1, 2)

## 最初のサブプロット (ax1) にプロットします
ax1.plot(x, y1)
ax1.set_title('Sine Wave')

## 2 番目のサブプロット (ax2) にプロットします
ax2.plot(x, y2, 'tab:orange')
ax2.set_title('Cosine Wave')

## 図を新しいファイルに保存します
plt.savefig('plot3.png')

print("Figure saved as plot3.png")

上記のコードでは、ax2.plot() の呼び出しに 'tab:orange' を追加して線の色を変更し、プロットを視覚的に区別できるようにしました。

ターミナルからスクリプトを再度実行します。

python3 main.py

出力は次のようになります。

Figure saved as plot3.png

これで、plot3.png を開いてください。隣り合った 2 つのプロットを含む完全な図が表示されます。ただし、タイトルや軸ラベルが少し窮屈に感じられるかもしれません。次のステップで修正します。

Plot3

plt.tight_layout() を使用してサブプロットのレイアウトを調整する

このステップでは、タイトルやラベルの重なりを防ぐために、サブプロット間の間隔を自動的に調整する方法を学びます。Matplotlib には、このための簡単な関数 plt.tight_layout() が用意されています。

この関数は、図上のすべてのアーティスト(タイトル、ラベル、プロット自体など)のバウンディングボックスを調べ、すべてが重ならずにきれいに収まるようにサブプロットパラメータを調整します。プロットを保存または表示する直前に呼び出すのが良い習慣です。

スクリプトに plt.tight_layout() を追加しましょう。main.py を以下のように更新してください。

import matplotlib.pyplot as plt
import numpy as np

## データの作成
x = np.linspace(0, 2 * np.pi, 400)
y1 = np.sin(x ** 2)
y2 = np.cos(x ** 2)

## 図とサブプロットのセットを作成します
fig, (ax1, ax2) = plt.subplots(1, 2)

## 最初のサブプロット (ax1) にプロットします
ax1.plot(x, y1)
ax1.set_title('Sine Wave')

## 2 番目のサブプロット (ax2) にプロットします
ax2.plot(x, y2, 'tab:orange')
ax2.set_title('Cosine Wave')

## 重なりを防ぐためにレイアウトを調整します
plt.tight_layout()

## 図を新しいファイルに保存します
plt.savefig('plot4.png')

print("Figure saved as plot4.png")

変更点は plt.tight_layout() 行が追加されただけです。これでスクリプトを実行します。

python3 main.py

出力:

Figure saved as plot4.png

plot4.png を開いて plot3.png と比較してください。2 つのサブプロット間の間隔が最適化され、よりクリーンでプロフェッショナルな見た目の図になっていることに気づくはずです。

Plot4

sharex=True または sharey=True を使用して軸を共有する

このステップでは、共通の軸を持つサブプロットを作成する方法を学びます。これは、同じ x 軸または y 軸スケールを持つデータセットを比較する場合に特に役立ちます。軸が共有されている場合、一方のサブプロットでのズームまたはパンは、もう一方を自動的に更新します。また、冗長な目盛りラベルを削除することで、図をすっきりさせるのにも役立ちます。

plt.subplots()sharex=True または sharey=True 引数を渡すことで、軸の共有を有効にできます。

これを実証するために、新しいスクリプトを作成しましょう。プロジェクトディレクトリに shared_axes.py という名前のファイルを作成し、次のコードを追加します。この例では、同じ x 軸を共有する 2 つのサブプロットを垂直に積み重ねて(nrows=2, ncols=1)作成します。

import matplotlib.pyplot as plt
import numpy as np

## データを作成します
t = np.arange(0.01, 5.0, 0.01)
s1 = np.exp(t)
s2 = np.sin(2 * np.pi * t)

## x 軸を共有する図と 2 つのサブプロットを作成します
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)

## 最初のサブプロットにプロットします
ax1.plot(t, s1, 'tab:blue')
ax1.set_ylabel('Exponential')

## 2 番目のサブプロットにプロットします
ax2.plot(t, s2, 'tab:orange')
ax2.set_ylabel('Sinusoidal')
ax2.set_xlabel('time (s)')

## レイアウトを調整します
plt.tight_layout()

## 図を保存します
plt.savefig('plot5.png')

print("Figure saved as plot5.png")

これで、この新しいスクリプトをターミナルから実行します。

python3 shared_axes.py

出力:

Figure saved as plot5.png

plot5.png を開きます。x 軸の目盛りラベルが下部のサブプロット(ax2)にのみ表示されていることに注意してください。これは、sharex=True が、よりクリーンな外観を作成するために、内部の x 軸ラベルを自動的に非表示にするためです。両方のプロットは x 軸に沿って完全に整列されており、比較が容易です。

Plot5

まとめ

実験はこれで完了です!Matplotlib でサブプロットを作成および管理するための基本的なテクニックを習得しました。

この実験では、以下のことを実践しました。

  • plt.subplots() を使用して、サブプロットのグリッドを持つ図を作成する。
  • 個々の Axes オブジェクトにアクセスし、そのメソッドを使用してデータをプロットする。
  • 特定のサブプロットにタイトルを追加する。
  • plt.tight_layout() を使用して間隔を自動調整し、要素の重なりを防ぐ。
  • sharex=True を使用して共有軸を持つサブプロットを作成し、より明確なデータ比較とクリーンな図を実現する。

これらのスキルは、複雑で情報量の多いデータ視覚化を作成するための基本となります。これで、複数のデータセットを単一のまとまりのあるビューで効果的に比較する図を作成できるようになりました。