Matplotlibはややこしい
Pythonでグラフを描くなら、Matplotlibの使用は避けて通れません。「Python グラフ」などで調べると、ほぼ確実にplt.plot
などMatplotlibの関数を見ることになるでしょう。
しかし、いざMatplotlibを使ってみようとしても、思ったように動作しないことが多いです。ネットからサンプルコードを探して、同じようにスクリプトを書いてみても、変なグラフができてしまったり、グラフが表示されないなどのトラブルに見舞われることがあります。
いったいなぜ、このような事態が起こるのでしょうか。それはもしかすると、Matplotlibに潜む「ややこしさ」が原因かもしれません。
本記事では、Matplotlibが持つ3つの「ややこしさ」について紹介します。Jupyter notebookでMatplotlibを動かすにあたって、これらを注意すれば上記のトラブルに遭遇する確率は減るかもしれません…。
1. plt.plotとax.plotの違い
Matplotlibをネット検索してみると、plt.plot
でグラフを描く方法と、ax.plot
でグラフを描く方法の2種類が存在することに気づくでしょう。
どうやら、Matplotlibには2種類の書き方の流派が存在するようです。plt.plot
はMATLABでの書き方を模したもので、ax.plot
はオブジェクト指向的な書き方となっています。
どちらが良い書き方なのかは正直判断できませんが、ax.plot
の方は画像情報をオブジェクトとして保存でき、必要に応じて加筆なども可能なので、こちらの書き方のほうが自分には合ってそうです。plt.plot
の方は、Jupyterのセルを跨いだときにどのように動作するのか予想できない怖さもあるので。
import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 10, 100) fig, axes = plt.subplots(2,1) axes[0] = axes[0].plot(x, np.sin(x)) axes[1].plot(x, np.cos(x))
オブジェクト指向的にMatplotlibでグラフを描画するには、上記のようにコードを書きます。ちなみに、fig
やaxes
というのはMatplotlibにおけるFigureクラスとAXESクラスを指します。これらが何者なのかはこの記事で詳しく説明されています。
2. Pandasのdf.plotの存在
いくつかの記事では、PandasのDataFrameをグラフ化する際に、DataFrameクラス自身が持つplotメソッドを使用していることがあります。実はこちらもMatplotlibで実装された機能なのですが、これは上記のMatplotlibの流派とどのように関わってくるのでしょうか。
このdf.plot
ですが、上記のfig
やaxes
と組み合わせて使うことができます。
import pandas as pd from sklearn import datasets iris = datasets.load_iris() df = pd.DataFrame(iris.data, columns=iris.feature_names) fig, axes = plt.subplots(1, 2, figsize=(8,4)) df.plot(ax=axes[0]) df.plot(ax=axes[1], kind='hist')
df.plot
にはaxes
を指定する引数が用意されています。ここに、作成済みのaxes
オブジェクトを指定すれば、そのaxes
にdf.plot
のグラフを格納することができます。
3. Jupyterでのfigure表示
Jupyter notebookでMatplotlibの画像を表示させるには、%matplotlib inline
というマジックコマンドを入力しなければならないと、調べると出てくると思います。しかし、%matplotlib inline
を入力しなくても、画像が勝手に表示されてしまうという経験がある方もいるでしょう。
それは、もしかするとMatplotlib backendのデフォルト設定が「inline」になっているからかもしれません。Google Colabでは、%matplotlib inline
を指定しなくてもbackendが「inline」に設定されていました。
Backendが「inline」になっていると、plt.show()
を記述しなくても作成されたcurrent figure
が表示されます。current figure
はplt.subplots()
でfig
が作られたときに格納され、plt.show()
で表示できます。
すなわち、Google ColabでMatplotlibを使う場合は、特にplt.show()
を書かなくても、勝手にcurrent figure
が表示されます。もし、画像を表示したくないときはplt.close()
を使います。
ちなみに、current figure
ではないfig
を表示したいときは、Jupyterではdisplay
関数で見ることができます。
fig, axes = plt.subplots(2,1) axes[0] = axes[0].plot(x, np.sin(x)) axes[1].plot(x, np.cos(x)) plt.close() display(fig)
まとめ
本記事では、Matplotlibに潜む3つのややこしさについて紹介しました。
- Matplotlibの書き方には、
plt.plot
とax.plot
の流派が存在する - 上記の流派とは別に、'df.plot'という書き方も存在する
- JupyterでMatplotlibの画像がいつ表示されるのかが分かりづらい
上記のややこしさに対して、本記事では下記のような解決策を選択しました。
- オブジェクト指向的な
ax.plot
の方が使いやすい df.plot
は既存のaxes
オブジェクトを引数に指定できる- Google Colabではinline指定は不要で、
plt.close()
やdisplay
関数などで表示のタイミングを指定できる
上記のややこしさを解消できれば、ネットに転がっているサンプルコードもより理解できるようになるでしょう。ぜひ参考にしてみてください。
以上です。