こんにちは,米国データサイエンティストのかめ(@usdatascientist)です.
データサイエンスのためのPython入門第21回です(講座の目次はこちら).今回は前回紹介したmatplotlibを使って,複数のグラフを並べて表示したいと思います.
(「データサイエンスのためのPython講座」動画版がでました!詳細はこちら)
これには,subplotという関数を使います.私は仕事で画像を扱うことが多いのですが,何枚もの画像を並べて表示するのに重宝してます.
また,matplotlibの優れた特徴として「オブジェクト指向」での記述が可能です.これによってより簡単に,わかりやすくコードを書くことが可能です.
それでは,順を追って解説しておきます!今回もなるべくわかりやすく,Step by Stepに進めていくので,付いてきてくださいね!
目次
subplotを使ってみる
といっても簡単です.plt.plot()の前にplt.subplot(row, column, index)を実行すると,row X columnの箱が確保され,index番目にグラフが描画されます.
説明するより実際に以下のコードを実行して実行結果をみた方が早いのではないかと思います.
1 2 3 4 5 6 7 8 9 |
x = np.linspace(-3, 3, 10) y1 = np.exp(x) y2 = x*x plt.subplot(1, 2, 1) plt.plot(x, y1) plt.subplot(1, 2, 2) plt.plot(x, y2) |
indexが0ではなく1から始まることに注意しましょう.試しに色々なグラフを複数描画してみてください!すぐ慣れると思います.
‘sub’というのは,「メインではない」「副の」という意味です.plotが「一つのでかいグラフを書くもの」だとしてたら,subplotは「小さいのをたくさん作るもの」というイメージです.「このイメージなので’sub’」と覚えておくといいかも
オブジェクト指向による記述(重要)
実はこのmatplotlib,オブジェクト指向での記述が可能になっています.「オブジェクト指向ってなに?」な方一旦気にしないでいただいてOKです.オブジェクト指向がなにかわかっていなくても今回解説する内容は理解できると思います.
Pythonのオブジェクト指向の書き方についてはこちらの動画講座でかなり詳しく解説をしているので,是非受講ください!
今まではplt.plot()やplt.subplot()のように直接pyplotモジュールの関数を呼び出していました.
まずはplt.figureオブジェクトを使ってplotしてみたいと思います.これによりより柔軟なコーディングが可能になりますし,特に複数のグラフを描画するような複雑なグラフを作る際はオブジェクト指向で書いたほうがいいと思います.ここではオブジェクト指向で複数のグラフを描画してみます.
- plt.figureオブジェクトを使って描画する
1 2 |
fig = plt.figure() type(fig) |
1 |
matplotlib.figure.Figure |
fig.add_subplot()でplotを追加し,axesオブジェクトを複数作っていきます.そのaxesオブジェクトに対してplot()関数をコールします.
1 2 3 4 5 6 |
fig = plt.figure() ax1 = fig.add_subplot(1, 2, 1) ax2 = fig.add_subplot(1, 2, 2) ax1.plot(x, y1) ax2.plot(x, y2) |
オブジェクト指向を勉強していない人は「クラス」「インスタンス」「オブジェクト」の言葉の意味がわからないかもしれません.
簡単にいうと,「クラス」というのは「インスタンス」の設計図のようなもので,「クラス」から個々の「インスタンス」を生成します.この「クラス」や「インスタンス」のことを総称して「オブジェクト」と言います.つまり,plt.figureという「クラス」があり,そこにはfigureオブジェクトを生成するための設計図が書かれています.そしてその設計図を元につくった’fig’が「インスタンス」であり,このインスタンスはfigureオブジェクトであると言えるのです.
・・・ややこし!別にわからなくてOKです.
さらに,このfigureオブジェクトとaxesオブジェクトをplt.subplots()で同時に作ることが可能です.subplot‘s’と複数形であることに注意してください.(この形をよく使います.重要です.)
1 2 |
# 1行2列のplotを作成 axesにはそれぞれのaxesオブジェクトがリストで返される fig, axes = plt.subplots(nrows=1, ncols=2) |
1 |
axes |
1 2 3 |
array([<matplotlib.axes._subplots.AxesSubplot object at 0x7f8c5523b610>, <matplotlib.axes._subplots.AxesSubplot object at 0x7f8c551d7d90>], dtype=object) |
axesインスタンスにはaxesオブジェクトがarrayになって格納されているのがわかります.つまり,それぞれのaxesオブジェクトに対してplot()関数をコールすることでグラフが描画されます.
1 2 3 |
fig, axes = plt.subplots(nrows=1, ncols=2) axes[0].plot(x, y1) axes[1].plot(x, y2) |
こんな感じです.よくこのaxesをfor文で回して大量のグラフや画像を描画することがあります.めちゃくちゃ便利ですよ!
一点注意が必要なのは, subplots() のnrowsが2以上ある場合,つまり2行以上のsubplotsを作る場合,axesは多次元arrayになります.
そのため,それぞれのaxesを使うためにはaxes[row_index, col_index]を指定します.
1 2 |
fig, axes = plt.subplots(nrows=3, ncols=3) print(axes.shape) |
1 |
(3, 3) |
1 2 |
fig, axes = plt.subplots(nrows=3, ncols=3) axes[1, 2].plot(x, y2) |
axesはNumPy Arrayなので当然indexは0から始まります.
色々説明しましたが,複数のグラフをplotする場合はこの fig, axes = plt.subplots(nrows, ncols) を使うことが多いです.この形を覚えてください.
なお,仮に一つのグラフしかplotしないとしても, fig, axes = plt.subplots() とし axes.plot(x, y) とすれば描画できます.(nrowsとncolsのデフォルト値は1です.) なので基本subplots()を覚えればOKです!
オブジェクト指向で付属情報をつける
前回の記事で, plt.xlabel() や plt.title() で軸にラベルをつけたりグラフにタイトルをつけました.
オブジェクト指向では基本,ax.set_xx()の形で同様に付属情報を付け加えることができます.legend()とaxis(‘off’)はそのままaxesオブジェクトから同様コールします.
1 2 3 4 5 6 7 8 9 10 |
fig, axes = plt.subplots(nrows=1, ncols=2) axes[0].plot(x, y1, label='something') axes[1].plot(x, y1) axes[0].set_xlabel('xlabel1') axes[0].set_ylabel('xlabel2') axes[0].set_title('plot title') axes[0].set_xticks([-3, -2, -1, 3]) axes[0].set_yticks([0, 10, 20]) axes[0].legend() axes[1].axis('off') |
前回の記事と見比べてください.前回の記事の内容が頭に入っていれば,すんなりと理解できるはずです!
まとめ
色々説明しましたが,一番重要なのは fig, axes = plt.subplots(nrows, ncols) です!これを説明するためにStep by Stepに説明したと思ってください.
axesはNumPy Arrayになっているので,それぞれのグラフにはaxes[行index, 列index]でアクセスしてください.一行しかない場合はaxes[列index]です.
複数のグラフを同時に表示したい時は結構多いです.特に画像を扱う場合は必須です.自分で色々なグラフを作ってみてください!自分で実際にコードを書かないといつまで経っても身につかないと思います.
それでは!
追記)次回はmatplotlibでplotしたグラフをPNGやPDFで保存する方法を解説します!最終的にはファイルに保存するのが普通なので,できるようにしましょう!