Pythonでグラフを描くときは、Matplotlib
を使うことが多いですね。
Matplotlibを使えば、複数のグラフをキレイに並べることができます。
しかし、初めのうちは次のようの問題に直面することも・・・:
Matplotlib
で一つの図の中に複数のグラフを並べるにはどうすればいいの?subplot
でグラフを並べられるらしいけど、使い方がよくわからない…。
そこで、この記事では複数グラフを並べるサブプロットについて、次の内容を図解付きで解説します。
plt.subplot()
の基本的な使い方|縦・横に並べる例- 【応用編】異なるサイズのグラフを並べる方法
plt.subplot()
でプロットをキレイに配置して、見やすく人に伝わるグラフを目指しましょう!
- plt.subplot()の概要
- plt.subplot()とplt.subplots()の違い
- plt.subplot()使用の流れ
- plt.subplot()の使用例
- plt.subplot()の便利な追加引数
- 【応用編】異なるサイズのグラフを並べる
- オススメ|matplotlibとデータ分析の勉強方法
plt.subplot()の概要
plt.subplot()
を使うと、一つの図の中に複数の小さなプロット(サブプロット)を複数配置できます。
この例では、一つの図の中に、コンター(左側)と、曲線(右側)を出力しています。
仮にJupyter Notebookでplt.subplot()
を使用しないと、次のように縦にズラーっと並びます。
plt.subplot()
を使うのと使わないのと、どちらが見やすいかは一目瞭然ですね!
plt.subplot()とplt.subplots()の違い
plt.subplot()
の使い方の説明の前に、名前が似ている関数plt.subplots()
との違いを確認しておきましょう。
どちらも一つの図の中に複数のグラフを作成するための関数ですが、使用方法は異なります。
plt.subplot()
でサブプロット領域を指定して、plt.plot()
などでプロットする方法fig, axes=plt.subplots()
で、複数のaxes
を生成してオブジェクト指向でプロットする方法
この記事では、1つ目のplt.subplot()
でサブプロットを作成する方法を紹介します。
fig, axes=plt.subplots()
を使用した、オブジェクト指向でのサブプロットについては、次の記事で解説します。
plt.subplot()使用の流れ
plt.subplot()
では、次のステップを繰り返して、一つの図の中にグラフを追加していきます。
plt.subplot()
でグラフを描く場所を指定plt.plot()
などでグラフを作成plt.subplot()
で別の場所を指定- 次のグラフを作成…(以後、繰り返し)
場所の指定、グラフの作成について、詳しく見ていきましょう。
subplot()でグラフを描く場所の指定
グラフを描く場所を指定するには、plt.subplot()
の引数に3つの整数LMN
を渡します。
import matplotlib.pyplot as plt
plt.subplot(LMN)
plt.subplot()
の引数LMN
は、次のルールに従ってサブプロットを描く場所を指定します。
L
,M
,N
:それぞれ一桁の正数- 図を縦に
L
個、横にM
個に分割 - 左上から数えて
N
番目の領域を指定
例えば、縦に2分割(L = 2
)、横に3分割(M = 3
)した場合の、各サブプロットの場所は下図のようになります。
各Nの値に応じて、次のようにサブプロットの場所が指定されます。
plt.subplot(231)
⇒ 左上を指定plt.subplot(236)
⇒ 右下を指定
指定場所にプロット作成
plt.subplot()
で場所を指定後に、plt
の各種メソッドでグラフを作成します。
次にplt.subplot()
で、別の場所が指定されるまで同じ位置のグラフが更新されるようになります。
例えば、plt.plot()を使用した折れ線グラフの作成方法については、次の記事を参考にしてください。
その他の各種グラフの作成方法については、以下の記事を参考にしてください。
以下では、plt.subplot()
の具体的な使用例を紹介していきます。
plt.subplot()の使用例
次のサンプルデータをもとにplt.subplot()
の使用例を紹介します。
import numpy as np
x = np.linspace(0, 3*np.pi, 100)
y1 = np.sin(x)
y2 = np.cos(x)
xはNumPy
のlinspace()
で[0, 3π]
を100等分した数列 x
です。
np.linspace()
の詳細は、次の記事を参考にしてください。
グラフを縦に並べる
縦にグラフを2つ並べる場合は、次のようにLMN
を指定します。
plt.subplot(LMN)
で、縦に2分割(L = 2
)、横に1分割(M = 1
)plt.subplot(211)
で、上のグラフの位置指定plt.subplot(212)
で、下のグラフの位置指定
実際にプロットを作成してみましょう。
# 1つ目のグラフ
plt.subplot(211)
plt.plot(x, y1)
# 2つ目のグラフ
plt.subplot(212)
plt.plot(x, y2, 'r--')
出力結果はこちらです。1つの図の中にグラフが縦に2つ並んでいます。
plt.plot()
でグラフを描く際の色や線のスタイルの設定については、次の記事を参考にしてください。
グラフを横に並べる
縦にグラフを2つ並べる場合は、次のようにLMN
を指定します。
plt.subplot(LMN)
で、縦に1分割(L = 1
)、横に2分割(M = 2
)plt.subplot(121)
で、左のグラフの位置指定plt.subplot(122)
で、右のグラフの位置指定
実際にプロットを作成してみましょう。
# 図のサイズを決める
# 1つ目のグラフ
plt.subplot(121)
plt.plot(x, y1)
# 2つ目のグラフ
plt.subplot(122)
plt.plot(x, y2, 'r--')
出力結果はこちらです。1つの図の中にグラフが横に2つ並んでいます。
右側のグラフの縦軸ラベルが、左側のグラフと被ってしまっています。
plt.figure(tight_layout=True)
を実行して、サブプロットの配置を自動調整すると見栄えがよくなります。
plt.figure(tight_layout=True)
# 1つ目のグラフ
plt.subplot(121)
plt.plot(x, y1)
# 2つ目のグラフ
plt.subplot(122)
plt.plot(x, y2, 'r--')
次の用に自動でサブプロットの配置が調整されます。
plt.figure()
によるFigureオブジェクト
の調整については、次の記事で詳しく解説しています。
グラフを縦横に並べる
縦横にグラフを2×2で並べる場合は、次のようにLMN
を指定します。
plt.subplot(LMN)
で、縦に2分割(L = 2
)、横に2分割(M = 2
)plt.subplot(221)
で、左上指定plt.subplot(222)
で、右上指定plt.subplot(223)
で、左下指定plt.subplot(224)
で、右下指定
実際にプロットを作成してみましょう。
# 左上のグラフ
plt.subplot(221)
plt.plot(x, y1)
# 右上のグラフ
plt.subplot(222)
plt.plot(x, y2, 'r--')
# 左下のグラフ
plt.subplot(223)
plt.plot(x, y1**2, "g.")
# 右下のグラフ
plt.subplot(224)
plt.plot(x, y2**2, 'c-.')
出力結果はこちらです。1つの図の中にグラフが2×2で並んでいます。
plt.subplot()の便利な追加引数
plt.subplot()
の追加引数で、サブプロットのグラフ設定を変更することができます。
特に便利な引数を次の表にまとめています。
設定内容 | 引数 | 対応するplt.メソッド |
---|---|---|
サブプロットのタイトル | title=("タイトル") |
plt.title("タイトル") |
軸の最大最小値 | xlim=(最小値, 最大値) ylim=(最小値, 最大値) |
plt.xlim(最小値, 最大値) plt.ylim(最小値, 最大値) |
軸ラベル名 | xlabel=("x軸ラベル名") ylabel=("y軸ラベル名") |
plt.xlabel("x軸ラベル名") plt.ylabel("y軸ラベル名") |
軸の共有 | sharex=共有先のaxオブジェクト sharey=共有先のaxオブジェクト |
— |
表右側にある対応するplt.メソッド
を実行しても、各種設定はできますが、引数で指定した方がスッキリします。
各引数の設定例をサンプルコートで確認してみましょう。
タイトルの設定
各サブプロットにタイトルを設定する場合は、引数title
を指定します。
plt.subplot(title=("タイトル"))
また、グラフ全体のタイトルを設定する場合は、plt.suptitle()
で別途指定します。
plt.suptitle("グラフ全体のタイトル")
グラフ全体のタイトル、サブプロットのタイトル設定例をあわせて見てみましょう。
# グラフ全体の設定
plt.figure(tight_layout=True)
# 1つ目のグラフ
plt.subplot(211, title="sine curve")
plt.plot(x, y1)
# 2つ目のグラフ
plt.subplot(212, title="cosine curve")
plt.plot(x, y2, 'r--')
次のようにタイトルが設定されます。
軸の最大値・最小値の設定
x軸、y軸の最大値・最小値はそれぞれxlim
, ylim
で指定できます。
plt.subplot(xlim=(最小値, 最大値), ylim=(最小値, 最大値))
x軸、y軸の最大値・最小値の設定例を見てみましょう。
# グラフ全体の設定
plt.figure(tight_layout=True)
# 1つ目のグラフ
plt.subplot(211, xlim=(0,2*np.pi), ylim=(-2,2))
plt.plot(x, y1)
# 2つ目のグラフ
plt.subplot(212)
plt.plot(x, y2, 'r--')
次のように軸の最大値・最小値が変更されています。
- グラフの軸のより詳しい解説は次の記事を参考にしてください。
軸ラベル名の設定
x軸、y軸のラベル名はそれぞれxlabel
, ylabel
で指定できます。
plt.subplot(xlim=(最小値, 最大値), ylim=(最小値, 最大値))
x軸、y軸の最大値・最小値の設定例を見てみましょう。
# グラフ全体の設定
plt.figure(tight_layout=True)
# 1つ目のグラフ
plt.subplot(211, xlabel="x-value", ylabel="y-value (sine)")
plt.plot(x, y1)
# 2つ目のグラフ
plt.subplot(212, xlabel="x-value", ylabel="y-value (sine)")
plt.plot(x, y2, 'r--')
次のように軸ラベルが設定されています。
- グラフの軸のより詳しい解説は次の記事を参考にしてください。
サブプロット間での軸の共有
サブプロット間でx軸またはy軸を共有する場合は、それぞれ次の引数を使用します。
sharex=共有先のaxオブジェクト
sharey=共有先のaxオブジェクト
ここでは、ax
オブジェクトは、各サブプロットのことだと思ってください。
次のように軸の共有元axを準備して、共有先にサブプロットに渡します。
- 軸の共有元のサブプロット生成時に、
ax = plt.subplot()
としてax
を準備 - 軸の共有先のサブプロット生成時に、
pls.subplot(sharex=ax)
でax
を渡す
サンプルコードで実行例を見てみましょう。
# グラフ全体の設定
plt.figure(tight_layout=True)
# 1つ目のグラフ
ax = plt.subplot(211, xlim=[0,9])
plt.plot(x, y1)
# 2つ目のグラフ
plt.subplot(212, sharex=ax, xlabel="x-value")
plt.plot(x, y2, 'r--')
サブプロット間のx軸が共有されているので、1つ目のグラフの最大値・最小値を設定すると、2つ目のx軸も同じように変化します。
- 軸の共有まで設定する場合には
fig, axes=plt.subplots()
を使用したオブジェクト指向プロットの方がおススメです。次の記事を参考にしてください。
【応用編】異なるサイズのグラフを並べる
plt.subplot()
の領域指定を工夫すると、サイズの異なるグラフを一つの図の中に表示することもできます。
# 標準正規分布を計算する関数
def f_norm(x):
return 1/np.sqrt(2*np.pi)*np.exp(-0.5*x**2)
# xとyの値を準備
x = np.linspace(-2, 2, 100)
y = np.linspace(-2, 2, 100)
# z は正規分布の積
z = np.tensordot( f_norm(x), f_norm(y), axes=0)
# 左半分にコンター
plt.figure(figsize=(10,5))
plt.subplot(121)
plt.contourf(x,y,z)
# 右半分にプロット
plt.subplot(322)
plt.plot(y,z[30,:], "--")
plt.ylim(0,0.2)
plt.subplot(324)
plt.plot(y,z[50,:], "r")
plt.ylim(0,0.2)
plt.subplot(326)
plt.plot(y,z[90,:], "c-.")
plt.ylim(0,0.2)
出力結果はこちらです。
ポイントになるのはのplt.subplot()
の領域指定方法です。
plt.subplot(121)
で、図の左半分を指定plt.subplot(322)
で、図の右上を指定plt.subplot(324)
で、図の右中央を指定plt.subplot(326)
で、図の右下を指定
下図のように、領域が重ならないようにplt.subplot()
の位置指定をしています。
使用済みの領域を指定すると、先に描いていたグラフは表示されないという点に注意しましょう。
上の例ではコンターで使用済み領域(321)
、(323)
、(325)
に、後からグラフを追加してしまうと、コンターは表示されなくなります。
オススメ|matplotlibとデータ分析の勉強方法
今回は、plt.subplot()
を用いて、一つの図の中に複数のグラフを並べる方法を紹介しました。
matplotlib
は奥の深いモジュールですが、なかなかわかりにくい部分もあります…。
そこで、グラフの作成方法、種類変更、凡例、タイトルの設定など網羅的にわかりやすく整理した記事を作りました。ぜひ参考にしてみてください。
また、データ分析初心者の方にはこちらの記事もおススメです。
私がこれまで勉強してきた経験をもとに考えたおススメの勉強本の紹介記事です。
何から始めて、どうやってレベルアップしていけばいいのか、初心者の方にぜひおススメしたい本を紹介しました。