Matplotlibで複数のグラフを並べて描く方法

Matplotlibで複数のグラフを並べて描く方法

データ解析を行うときはグラフで可視化、並べて関連性を確認するケースが多くあります。Pythonでデータをグラフ化する際はMatplotlibの利用が簡単で便利です。今回は複数のグラフを自由自在に配置する方法を記載します。
Matplotlib複数グラフ

Matplotlibで複数グラフを自由自在にレイアウトする方法




グラフオブジェクトと描画領域を理解する

Matplotlibで複数のグラフを自在にレイアウトするには、グラフを配置する領域の理解がポイントです。Matplotlibではfigureオブジェクトとaxesオブジェクトを使いグラフを描画します。

figureはグラフを配置する外枠の領域、axesがグラフでデータをプロットする領域です。 figureが親でaxesが子の関係で、figureの中に複数のaxesを設置できます。

下のキャプチャ画はPythonインタラクティブシェルからMatplotlibでグラフ出力した例です。

  • figureのみ(axesなし)
    figureのみ(axesなし)
  • figure>axes(1個追加)
    figure>axes(1個追加)
  • figure>axes(2個追加)
    figure>axes(2個追加)
  • figure>axes(4個追加)
    figure>axes(4個追加)
figure(枠)も同時に複数作成できますが、今回は一つのfigureに複数のaxes(グラフ)を設置する方法で記載します。 また、以降のグラフ描画はJupyter Notebook利用して出力しています。

オブジェクト指向形式でコードを書く


Matplotlibでグラフを作成する表記方法として、対話形式とオブジェクト指向形式の二通りがあります。どちらの表記でも同じグラフが作成できますが、複数のグラフを扱う場合はオブジェクト指向の表記を覚えておくと何かと便利です。

複数のグラフを対話形式で記載した場合、操作対象が分かり難くなる傾向があります。オブジェクト指向形式で覚えておくと、複雑な作図処理にも応用が利きます。


対話形式とオブジェクト指向形式のコード表記(例)
In [1]:
%matplotlib inline
import matplotlib.pyplot as plt

In [2]:
# ① 対話形式の表記例

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()

In [3]:
# ②-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()

In [4]:
# ②-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をベースに記載していきます。


大まかな処理の流れは以下の通りです。
  1. matplotlibをインポートする
  2. figureオブジェクト(外枠)の作成する
  3. axesオブジェクト(グラフ)をfigureに追加する
  4. グラフデータをaxesオブジェクトに設定する
  5. 軸やラベルなどを任意に設定する
  6. 3~5をグラフ描画分繰り返す

matplotlibのインポート

慣例でMatplotlibのインポートは以下のように記載します。環境に応じてMatplotlibの事前にインストールが必要です。Anacondaで一括インストールするとJupyter Notebookもすぐ利用できるため便利です。
In [1]:
%matplotlib inline
import matplotlib.pyplot as plt # matplotlibインポート
「%matplotlib inline」はJupyter Notebookでインライン表示する宣言です。

figure作成(グラフを入れる領域)

figureは、plt.figure()で作成できます。オプション引数figsize(省略可)でfigureの大きさを指定できます。
  • plt.figure(figsize=(横サイズ, 縦サイズ))
  • デフォルトはfigsize=(8, 6)
  • サイズはインチ単位で指定
ここでは作成したfigureオブジェクトを変数figに格納しています。
In [2]:
fig = plt.figure(figsize=(9, 6)) # figureオブジェクト作成
<matplotlib.figure.Figure at 0x1454a564940>

Jupyter Notebookインライン表示でfigureだけ作成した場合、枠画像などは特に出力されません(作成されたオブジェクト名とアドレスだけ表示されます)。


axes追加(データプロットするグラフ領域)

作成済みのfigureオブジェクトにaxesオブジェクトを追加するには(figure object).add_subplot(縦の分割数 ,横の分割数, 順序)を利用します。

以下はレイアウトが2行3列(2×3で6分割)で、順序1(左上)と順序3(右上)、順序5(下中央)の3つ位置にaxesを追加した例です。

In [1]:
%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個を一括で追加したコードを以下に記載します。プロット用に簡易的なデータも設定しています。

In [2]:
%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(グラフ作るためのキホン)



スポンサーリンク

2 件のコメント :

  1. matplotlibに関する記事は、対話型形式とオブジェクト志向形式が混在しているものが多く、混乱しておりました。しかし、こちらの記事で霧が晴れた気がします。大変参考になりました。

    返信削除
    返信
    1. コメントありがとうございます。グラフの作り方をよく忘れてしまうため、備忘録として書いた記事ですが、少しでもお役に立てて嬉しいです。

      削除