【日本語で解説】matplotlibチュートリアル(後編)

こんにちは、unogram管理人のうのちゅ〜です。

今回は、Pythonによるプロットの基礎として、matplotlibのチュートリアルを活用した学習について前後編に分けて解説していきます。

matplotlib.pyplotを使うと、MATLABのようにグラフをプロットすることができます。有料ソフトウェアであるMATLABのような機能をPythonのライブラリとして使用できるのはとてもありがたいですよね。

とはいえ、matplotlibには膨大な機能があり、うまく使いこなせていない方も多いのではないかと思います。

matplotlibの基礎は、公式のmatplotlibチュートリアルを参考にした学習がおすすめです。とはいえ英語で記載されていたり、そのままのコードで実行してもうまくいかない部分があるため、解説や修正を加えながら日本語で解説していきます。

前編の続きとなっているので、【日本語で解説】matplotlibチュートリアル(前編)からご覧いただくと分かりやすいかと思います。

それでは見ていきましょう!



日本語で解説!matplotlibチュートリアル(後編)

複数の図・軸の操作

MATLABとpyplotには、現在の図(current figure)と現在の軸(current axes)という概念があります。各種のプロット関数は、全て現在の軸に適用されます。

関数gcaは現在の軸を、関数gcfは現在の図を返します。通常は内部的に行われる処理なので意識する必要はありません(ちなみに、現在の図をクリアしたい場合はclf、現在の軸をクリアしたい場合はclaです)。

特別に指定しなければ、図はfigure(1)として生成され、subplot(111)にプロットされます。

次の例では、2つのサブプロット(subplot)を生成します。
plt.subplot(numrow,numcol,k)は、numrow行numcol列のプロットのマトリクスを生成します。kは、1〜numrownumcolの数値で、プロットの位置を指定します。カンマはオプションで、numrownumcol<10であれば不要です。

def f(t):
    return np.exp(-t) * np.sin(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

plt.figure()
plt.subplot(211)
plt.plot(t1, f(t1), 'ro', t2, f(t2), 'r')

plt.subplot(212)
plt.plot(t2, np.sin(2*np.pi*t2), 'b--')
plt.show()

plt.figureによって複数のfigureを生成することも可能で、それぞれのfigureが任意のsubplotを保持することができます。

plt.figure(1)                # 1つ目のfigure
plt.subplot(211)             # 1つ目のfigureの1つ目のsubplot
plt.plot([1, 2, 3])
plt.subplot(212)             # 1つ目のfigureの2つ目のsubplot
plt.plot([4, 5, 6])


plt.figure(2)                # 2つ目のfigure
plt.plot([4, 5, 6])          # subplotを指定しない場合デフォルトで(111)に

plt.figure(1)                # 1つ目のfigureを現在の図に。この時点では(212)が現在の軸。
plt.title('Figure 1, subplot 2') # 現在の軸にタイトルを設定
plt.subplot(211)             # 1つ目のfigureの1つ目のsubplotを現在の軸に設定
plt.title('Figure 1, subplot 1') # 現在の軸にタイトルを設定
plt.tight_layout() #上下の幅の調整に使用
plt.savefig('./mat10.png')

たくさんの図を生成した場合、明示的にcloseするようにしましょう。図のウィンドウを閉じるなどしただけでは、メモリは完全には解放されません。

テキストの扱い

任意の位置にtextを追加することができますが、xlabelやylabel、titleなどは所定の位置にテキストが追加されます。

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)

# the histogram of the data
n, bins, patches = plt.hist(x, 50, density=1, facecolor='g', alpha=0.75)


plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()

全てのtext関数は、matplotlib.text.Textインスタンスを返します。線のプロパティのように、キーワード引数やsetpを使ってカスタマイズすることが可能です。

t = plt.xlabel('my data', fontsize=14, color='red')

数式表現

matplotlibでは、どのtext表現においても、TeXのように数式表現することが可能です(別途TeX環境を構築しておく必要はありません)。上の例では、グラフ中のギリシャ文字が該当します。



アノテーション(注釈)

プロット中の特徴的な箇所に注釈をつけたい場合、plt.annotateによって簡単にアノテーションを行うことができます。

このとき、xyによってアノテーションされる箇所を指定し、xytextによってテキストの位置を指定します。どちらも(x,y)のタプルで表します。

ax = plt.subplot(111)

t = np.arange(0.0, 3.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)

plt.annotate('local max', xy=(1, 1), xytext=(2, 1.5),
             arrowprops=dict(facecolor='black', shrink=0.05),
             )

plt.ylim(-2, 2)
plt.show()

対数軸やその他の非線形軸

matplotlib.pyplotでは、線形軸だけでなく対数軸やlogitスケールに対応しています。

軸のスケール変換は、plt.xscale(‘log’)などとして簡単に行うことができます。

次の例は、同一のデータに対し、y軸のスケールを変化させて複数種類のプロットを行う例です。

from matplotlib.ticker import NullFormatter  # 今回はlogitスケールに使用します。

# 乱数シードの指定
np.random.seed(19680801)

# プロットデータを生成します。
y = np.random.normal(loc=0.5, scale=0.4, size=1000)
y = y[(y > 0) & (y < 1)]
y.sort()
x = np.arange(len(y))

# 適当な図サイズを指定しています。
plt.figure(figsize = (10,6))

# linear(線形)
plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)

# log(対数)
plt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)

# symmetric log(対称log):正負両方の数の対数プロット
plt.subplot(223)
plt.plot(x, (y - y.mean()))
# linthresh=x0とすると、(-x0,x0)の範囲で線形にプロットし、0付近で発散することを防ぎます。
plt.yscale('symlog', linthreshy=0.01) #linthreshではなく、linthreshyとしてしきい値を設定する点に注意しましょう。
plt.title('symlog')
plt.grid(True)

# logit
plt.subplot(224)
plt.plot(x, y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)
# y軸ラベルの副目盛りが多すぎる場合は、以下のようにして副目盛りを空の文字列に設定します。
plt.gca().yaxis.set_minor_formatter(NullFormatter())

plt.tight_layout()
plt.show()



まとめ

今回はPythonによるプロットの基礎として、matplotlibのチュートリアルを活用した学習について、前後編に分けて解説してきました。後編では、テキストの追加や複数グラフのプロット方法について知ることができたのではないかと思います。

チュートリアルを越えてより詳しく学びたいという方は、下記の参考書などを使った学習にも挑戦してみてください。

参考書学習は…

matplotlibのみを扱った参考書は少ないですが、numpyやpandasを含めて、データサイエンスに必要なライブラリを詳しく解説する以下の書籍がおすすめです。

また、どんなグラフを作ると効果的なのかわからず、雰囲気でグラフを作っていた方は、以下の書籍で効果的なグラフの選択について学ぶのも良いでしょう。

参考

matplotlibチュートリアル