YutaKaのPython教室

Python の文法やライブラリ、API、環境構築について画像・動画・ソースコード付きで徹底解説!

Matplotlib plt.subplotの使い方徹底図解|一つの図に複数グラフを描く

Pythonでグラフを描くときは、Matplotlibを使うことが多いですね。

Matplotlibを使えば、複数のグラフをキレイに並べることができます。

しかし、初めのうちは次のようの問題に直面することも・・・:

  • Matplotlibで一つの図の中に複数のグラフを並べるにはどうすればいいの?
  • subplotでグラフを並べられるらしいけど、使い方がよくわからない…。

そこで、この記事では複数グラフを並べるサブプロットについて、次の内容を図解付きで解説します。

  • plt.subplot()の基本的な使い方|縦・横に並べる例
  • 【応用編】異なるサイズのグラフを並べる方法

plt.subplot()でプロットをキレイに配置して、見やすく人に伝わるグラフを目指しましょう!

plt.subplot()の概要

plt.subplot()を使うと、一つの図の中に複数の小さなプロット(サブプロット)を複数配置できます。

この例では、一つの図の中に、コンター(左側)と、曲線(右側)を出力しています。

仮にJupyter Notebookでplt.subplot()を使用しないと、次のように縦にズラーっと並びます。

plt.subplot()を使うのと使わないのと、どちらが見やすいかは一目瞭然ですね!

plt.subplot()とplt.subplots()の違い

plt.subplot()の使い方の説明の前に、名前が似ている関数plt.subplots()との違いを確認しておきましょう。

どちらも一つの図の中に複数のグラフを作成するための関数ですが、使用方法は異なります。

  1. plt.subplot()でサブプロット領域を指定して、plt.plot()などでプロットする方法
  2. fig, axes=plt.subplots()で、複数のaxesを生成してオブジェクト指向でプロットする方法

この記事では、1つ目のplt.subplot()でサブプロットを作成する方法を紹介します。

fig, axes=plt.subplots()を使用した、オブジェクト指向でのサブプロットについては、次の記事で解説します。

≫Matplotlib plt.subplots()の使い方|FigureとAxesを同時生成!
Matplotlibでグラフを描くとき「fig, ax = plt.subplots()って、よく見るけど何してるの?」「plt.subplots()の便利な使い方を知りたい! 」という方のために、plt.subplots()でFigureとAxesを作ると何が便利なのか、plt.subplots()の基本的な使い方、覚えておくと便利なplt.subplots()の引数をを図解付きで解説します!
www.yutaka-note.com/entry/matplotlib_subplots
 

plt.subplot()使用の流れ

plt.subplot()では、次のステップを繰り返して、一つの図の中にグラフを追加していきます。

  1. plt.subplot()でグラフを描く場所を指定
  2. plt.plot()などでグラフを作成
  3. plt.subplot()で別の場所を指定
  4. 次のグラフを作成…(以後、繰り返し)

場所の指定、グラフの作成について、詳しく見ていきましょう。

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()を使用した折れ線グラフの作成方法については、次の記事を参考にしてください。

≫Matplotlib plt.plot徹底解説 | 基本操作を総まとめ!
Matplotlibのplt.plotを使用したグラフを作成、グラフの見た目変更、タイトルや軸の設定など基本事項について徹底解説!!この記事を読めば、plt.plotで手軽に手早く簡単に、キレイなグラフ作成可能に!?
www.yutaka-note.com/entry/matplotlib_pyplot
 

その他の各種グラフの作成方法については、以下の記事を参考にしてください。

≫【初心者向け】Matplotlibの特徴と使い方をわかりやすく解説!
脱初心者のためのMatplotlibマスターガイドです。そもそもどういう流れでプロットするのか?どんな種類のグラフが描けるのか?日本語設定は?タイトルや軸の設定は?オブジェクト指向って何?そんな疑問を解決します!この記事で、脱Matplotlib初心者を目指そう!
www.yutaka-note.com/entry/matplotlib_guid
 

以下では、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はNumPylinspace()[0, 3π]を100等分した数列 x です。

np.linspace()の詳細は、次の記事を参考にしてください。

≫【徹底図解】NumPy linspace | お手軽!等間隔の数列を作成
NumPyで、等間隔の数列を作るにはどうすればいいの?!そんな疑問にお答えします。等間隔の数列を生成するには、NumPyの関数linspace()を使いましょう!この記事では、linspaceの使い方を、図解・サンプルコード付きで紹介します。類似関数arrangeとの使い分けについても、しっかり解説しています!
www.yutaka-note.com/entry/numpy_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()でグラフを描く際の色や線のスタイルの設定については、次の記事を参考にしてください。
≫Matplotlib plt.plot徹底解説 | 基本操作を総まとめ!
Matplotlibのplt.plotを使用したグラフを作成、グラフの見た目変更、タイトルや軸の設定など基本事項について徹底解説!!この記事を読めば、plt.plotで手軽に手早く簡単に、キレイなグラフ作成可能に!?
www.yutaka-note.com/entry/matplotlib_pyplot
 

グラフを横に並べる

縦にグラフを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オブジェクトの調整については、次の記事で詳しく解説しています。
≫Matplotlib plt.figure()を使う理由|FigureとAxesの関係を把握しよう
Matplotlibでグラフを描くとき「FigureとかAxesとかMatplotlib独特の単語が多くてよくわからない」、「Figureを作った後、結局どうやってプロットすればいいの?」という方のために、FigureとAxesの関係性を図解!FigureにAxesを追加する方法厳選3パターンを解説します!覚えておきたいFigureの設定・操作(サイズ変更、レイアウト調整など)も画像・サンプルコード付きで解説!
www.yutaka-note.com/entry/matplotlib_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--')

次のように軸の最大値・最小値が変更されています。

  • グラフの軸のより詳しい解説は次の記事を参考にしてください。
≫Matplotlib 軸周り完璧マスターガイド | 軸・軸目盛・目盛り線の設定
Matplotlibで大変なのが軸周りの設定!グラフの「この要素」を変更するには、「どのメソッド」を使えばいいのかわからない…。という方のために、Matplotlibの軸・目盛り・目盛り線の設定について総まとめしました!これで軸周りの設定がだいぶ楽になります。軸周り完ぺきマスターガイド!
www.yutaka-note.com/entry/matplotlib_axis
 

軸ラベル名の設定

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

次のように軸ラベルが設定されています。

  • グラフの軸のより詳しい解説は次の記事を参考にしてください。
≫Matplotlib 軸周り完璧マスターガイド | 軸・軸目盛・目盛り線の設定
Matplotlibで大変なのが軸周りの設定!グラフの「この要素」を変更するには、「どのメソッド」を使えばいいのかわからない…。という方のために、Matplotlibの軸・目盛り・目盛り線の設定について総まとめしました!これで軸周りの設定がだいぶ楽になります。軸周り完ぺきマスターガイド!
www.yutaka-note.com/entry/matplotlib_axis
 

サブプロット間での軸の共有

サブプロット間でx軸またはy軸を共有する場合は、それぞれ次の引数を使用します。

  • sharex=共有先のaxオブジェクト
  • sharey=共有先のaxオブジェクト

ここでは、axオブジェクトは、各サブプロットのことだと思ってください。

次のように軸の共有元axを準備して、共有先にサブプロットに渡します。

  1. 軸の共有元のサブプロット生成時に、ax = plt.subplot()としてaxを準備
  2. 軸の共有先のサブプロット生成時に、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()を使用したオブジェクト指向プロットの方がおススメです。次の記事を参考にしてください。
≫Matplotlib plt.subplots()の使い方|FigureとAxesを同時生成!
Matplotlibでグラフを描くとき「fig, ax = plt.subplots()って、よく見るけど何してるの?」「plt.subplots()の便利な使い方を知りたい! 」という方のために、plt.subplots()でFigureとAxesを作ると何が便利なのか、plt.subplots()の基本的な使い方、覚えておくと便利なplt.subplots()の引数をを図解付きで解説します!
www.yutaka-note.com/entry/matplotlib_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は奥の深いモジュールですが、なかなかわかりにくい部分もあります…。

そこで、グラフの作成方法、種類変更、凡例、タイトルの設定など網羅的にわかりやすく整理した記事を作りました。ぜひ参考にしてみてください。

≫【初心者向け】Matplotlibの特徴と使い方をわかりやすく解説!
脱初心者のためのMatplotlibマスターガイドです。そもそもどういう流れでプロットするのか?どんな種類のグラフが描けるのか?日本語設定は?タイトルや軸の設定は?オブジェクト指向って何?そんな疑問を解決します!この記事で、脱Matplotlib初心者を目指そう!
www.yutaka-note.com/entry/matplotlib_guid
 

また、データ分析初心者の方にはこちらの記事もおススメです。

私がこれまで勉強してきた経験をもとに考えたおススメの勉強本の紹介記事です。

何から始めて、どうやってレベルアップしていけばいいのか、初心者の方にぜひおススメしたい本を紹介しました。

≫独学でデータ分析を勉強するオススメ学習本
独学でのpythonデータ分析勉強に役立ったおススメ書籍を紹介していきます。業務でそれなりにデータ分析を行えるまで、いろいろな試行錯誤をしてきましたが、もし自分が今ゼロから勉強する立場ならどうするのがいいのか考えてみました。以下では、入門書、個別モジュール用、実践用の3つの視点でおススメ本を紹介していきます。
www.yutaka-note.com/entry/data_analysis