データ分析において、複雑なデータを人間の見やすい形(グラフなど)に可視化することは重要な作業だ。

Pythonにはデータの可視化をおこなうライブラリが沢山用意されているが、ここではMatplotlibを主として取り上げていく。

Matplotlibのセットアップ

Jupyter NotebookでMatplotlibを使う場合、まず下記のコードを実行する必要がある。

%matplotlib notebook

続いて下記のimport文を書こう。

import matplotlib.pyplot as plt

簡単なプロットを実行してみる

必要なセットアップが完了したら、下記の簡単なサンプルコードを書いて実際にプロットしてみよう。

import numpy as np

data = np.arange(10)
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

plt.plot(data)

サブプロットを作る

Matplotlibのプロット機能は、Figureオブジェクトに含まれており、新規で図を作る場合はfigureメソッドを使う。

fig = plt.figure()

上記コマンドを実行してもJupyterでは何も表示されない。
空の図には何もプロットすることができないので、サブプロット(グラフを描く領域)を少なくとも一つ以上作る必要がある。

ax1 = fig.add_subplot(2, 2, 1)

上記のadd_subplotはサブプロットを作るメソッドで、引数の意味としては「レイアウトを2 × 2として、一つ目を選択する」ということだ。

この後、以下のコードを実行すると次のようなプロットが現れる。

ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
fig

Jupyter Notebookでプロットをおこなう場合の注意

なお、Jupyter NotebookでMatplotlibを使う場合、Jupyterの各セルが実行された後にプロットがリセットされてしまうことに注意が必要だ。

そのため、複雑なプロットをおこなう場合は、一つのセルに全てのプロット処理を書いて実行する必要がある。

そこで、ここまでのコマンドを一つのセルにまとめて実行し直そう。
※必要であればJupyter Notebookのカーネルを一度リセットしてくれ。

import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)

複数のプロットが用意された中でプロットを実行すると、Matplotlibはサブプロットの中で最後のものに描画をおこなう。

例えば以下のコマンドを実行すると得られる図は下記のとおりとなる。

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)

plt.plot(np.random.randn(50).cumsum(), 'k--')

ちなみに「k–」というオプションは線種を表しており、黒色の破線を表す。

指定のサブプロットへ直接プロットする

指定のサブプロットへ図を描画する場合は、以下のようにオブジェクトのインスタンスメソッドを呼び出せば良い。

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)

plt.plot(np.random.randn(50).cumsum(), 'k--')

_ = ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)
_ = ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))

ax1ではヒストグラムを描画するhistメソッドを、ax2では散布図を描画するscatterメソッドを呼び出した。

plt.subplotsメソッド

ここまで見てきた例のようにプロットを格子状に配置することは良くあることなので、これをより便利に扱うためのplt.subplotsというメソッドも用意されている。

このメソッドは新たに図を作成し、その中にサブプロットを作成、さらに作成したサブプロットオブジェクトを要素として持つNumpyの配列を戻してくれる。

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(2, 3)

サブプロットの周りの空白を調節する

デフォルトではサブプロットの周りに空白ができてしまう。

この空白を任意で調節する場合、Figureオブジェクトのsubplots_adjustメソッドを使う。

例としてサブプロット周りのスペースを無くしてみよう。

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)

for i in range(2):
    for j in range(2):
        axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5)
        
plt.subplots_adjust(wspace=0, hspace=0)

補足として、subplotsメソッドのオプションで指定したsharex、shareyで、x軸、y軸それぞれのラベルを共有するように設定している。
これでサブプロットの空白を無くした時の見栄えが良くなる。