Matplotlibで複数グラフを自由自在にレイアウトする方法
グラフオブジェクトと描画領域を理解する
Matplotlibで複数のグラフを自在にレイアウトするには、グラフを配置する領域の理解がポイントです。Matplotlibではfigureオブジェクトとaxesオブジェクトを使いグラフを描画します。figureはグラフを配置する外枠の領域、axesがグラフでデータをプロットする領域です。 figureが親でaxesが子の関係で、figureの中に複数のaxesを設置できます。
下のキャプチャ画はPythonインタラクティブシェルからMatplotlibでグラフ出力した例です。
-
figureのみ(axesなし)
-
figure>axes(1個追加)
-
figure>axes(2個追加)
-
figure>axes(4個追加)
オブジェクト指向形式でコードを書く
Matplotlibでグラフを作成する表記方法として、対話形式とオブジェクト指向形式の二通りがあります。どちらの表記でも同じグラフが作成できますが、複数のグラフを扱う場合はオブジェクト指向の表記を覚えておくと何かと便利です。
複数のグラフを対話形式で記載した場合、操作対象が分かり難くなる傾向があります。オブジェクト指向形式で覚えておくと、複雑な作図処理にも応用が利きます。
対話形式とオブジェクト指向形式のコード表記(例)
%matplotlib inline
import matplotlib.pyplot as plt
# ① 対話形式の表記例
plt.subplot(1, 2, 1)
plt.plot([0, 1],[0, 1],color="red")
plt.subplot(1, 2, 2)
plt.plot([0, 1],[0, 1],color="blue")
plt.show()
# ②-A オブジェクト指向の表記例
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
ax1.plot([0, 1],[0, 1], color="red")
ax2 = fig.add_subplot(1, 2, 2)
ax2.plot([0, 1],[0, 1], color="blue")
plt.show()
# ②-B オブジェクト指向の表記例
fig, ax = plt.subplots(1, 2)
ax[0].plot([0, 1],[0, 1], color="red")
ax[1].plot([0, 1],[0, 1], color="blue")
plt.show()
表記方法が異なるだけでグラフ出力結果は三つとも同じです。今回はオブジェクト指向的な書き方②-Aをベースに記載していきます。
大まかな処理の流れは以下の通りです。
- matplotlibをインポートする
- figureオブジェクト(外枠)の作成する
- axesオブジェクト(グラフ)をfigureに追加する
- グラフデータをaxesオブジェクトに設定する
- 軸やラベルなどを任意に設定する
- 3~5をグラフ描画分繰り返す
matplotlibのインポート
慣例でMatplotlibのインポートは以下のように記載します。環境に応じてMatplotlibの事前にインストールが必要です。Anacondaで一括インストールするとJupyter Notebookもすぐ利用できるため便利です。%matplotlib inline
import matplotlib.pyplot as plt # matplotlibインポート
figure作成(グラフを入れる領域)
figureは、plt.figure()で作成できます。オプション引数figsize(省略可)でfigureの大きさを指定できます。- plt.figure(figsize=(横サイズ, 縦サイズ))
- デフォルトはfigsize=(8, 6)
- サイズはインチ単位で指定
fig = plt.figure(figsize=(9, 6)) # figureオブジェクト作成
Jupyter Notebookインライン表示でfigureだけ作成した場合、枠画像などは特に出力されません(作成されたオブジェクト名とアドレスだけ表示されます)。
axes追加(データプロットするグラフ領域)
作成済みのfigureオブジェクトにaxesオブジェクトを追加するには(figure object).add_subplot(縦の分割数 ,横の分割数, 順序)を利用します。以下はレイアウトが2行3列(2×3で6分割)で、順序1(左上)と順序3(右上)、順序5(下中央)の3つ位置にaxesを追加した例です。
%matplotlib inline
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(9, 6)) # figureオブジェクト作成
# axesオブジェクト追加
ax1 = fig.add_subplot(2, 3, 1) # 2行3列分割レイアウトの順序1にaxes追加
ax3 = fig.add_subplot(2, 3, 3) # 2行3列分割レイアウトの順序3にaxes追加
ax5 = fig.add_subplot(2, 3, 5) # 2行3列分割レイアウトの順序5にaxes追加
plt.show()
add_subplotの3個の引数は、1個の引数にまとめて3桁数値で表記することもできます。
例)add_subplot(2, 3, 1) → add_subplot(231)
だだし個々のパラメターは10未満(一桁)が条件です。10以上のときはカンマ区切りを使う必要があります。
最後に反復処理でaxes(グラフ)6個を一括で追加したコードを以下に記載します。プロット用に簡易的なデータも設定しています。
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
rows_count = 2 # 2行
columns_count = 3 # 3列
graphs_count = rows_count * columns_count # グラフ6個(2*3)
axes = [] # axesオブジェクト保持用
x = np.linspace(-1, 1, 100) # x軸データ
fig = plt.figure(figsize=(9,6 )) # figureオブジェクト作成
for i in range(1, graphs_count + 1):
axes.append(fig.add_subplot(rows_count, columns_count, i)) # 順序i番目のAxes追加
y = x ** i # y軸データ(n次式)
axes[i-1].plot(x, y)
#テキスト挿入
plot_memo = "Axes." + str(i)
axes[i-1].annotate(plot_memo, xy=(0.5, 0.8), fontsize=16, xycoords='axes fraction', horizontalalignment='center')
fig.subplots_adjust(wspace=0.3, hspace=0.3) # グラフ間の隙間調整
plt.show()
グラフは記事冒頭と同じものです。
こちらの記事にも詳しく記載しました。
もものきとPython/Matplotlibでグラフを描いてみよう01(グラフ作るためのキホン)
matplotlibに関する記事は、対話型形式とオブジェクト志向形式が混在しているものが多く、混乱しておりました。しかし、こちらの記事で霧が晴れた気がします。大変参考になりました。
返信削除コメントありがとうございます。グラフの作り方をよく忘れてしまうため、備忘録として書いた記事ですが、少しでもお役に立てて嬉しいです。
削除