Pynote

Python、機械学習、画像処理について

matplotlib - matplotlib の使うために理解するべき基本要素

3つのレイヤー

matplotlib は、Backend レイヤー、Artist レイヤー、Script レイヤーという3つのレイヤーから構成される。
一番下のレイヤーは、自身のインタフェースのみ知っていればよく、それに続くレイヤーは自身及びその下のレイヤーのみ知っていればよい。各役割ごとにレイヤーが分離されているので、機能拡張がしやすい作りになっている。

backend レイヤー

backend レイヤーは、描画エンジン、キャンバス、イベントを表す抽象クラス及び実際の出力対象に応じた実装を提供する具象クラスを提供する。

backend はマウスやキーワードで操作できる GUI と pdf、png などのハードコピー (hardcopy) に分類される。さらにハードコピーはラスター画像 (raster graphics) とベクター画像 (vector graphcis) に分類される。


Artist レイヤー

図はタイトル、線、目盛り、テキストなどで構成されるが、matplotlib ではこれらのオブジェクトを Artist と呼んでいる。
Artist には、テキストや線など基本要素を表す primitive タイプと Figure、Axes など複数の Artist を束ねる container タイプがあり、階層構造を持つ。

The Architecture of Open Source Applications (Volume 2): matplotlib から引用

この中で最も重要な Artist は Axes である。
Axes には、データを描画するための便利関数が多数定義されている。
例えば、折れ線グラフは複数の線 (matplotlib.lines.Line2D) から構成されるが、Axes.plot() を使用すると、これらの Artist をデータに応じて自動で作成する。

Artist レイヤーは抽象クラスの Artist 及び描画するオブジェクトごとに具象クラスを提供する。
具象クラスでは、backend レイヤーで定義された描画エンジンを使用して、自身を描画する方法が実装されている。

Script レイヤー

matplotlib は、これまで説明したようにオブジェクト指向で設計されている。script レイヤーは、この部分をラップし、Matlab のようにスクリプト言語風に利用できる API を提供する。
これらの API は matplotlib.pyplot モジュールに定義されている。

pyplot は便利であるが、state machine であることを理解して使う必要がある。

以下のヒストグラムを描画するコードを例に見ていく。

import matplotlib.pyplot as plt
import numpy as np

# 標準正規分布に従う (1000,) の numpy 配列を作成する。
x = np.random.normal(0, 1, 1000)

# ヒストグラムを描画する。
plt.hist(x, 100)

# タイトルを設定する。
plt.title(r'Normal distribution with $\mu=0, \sigma=1$')

# 表示する。
plt.show()


1. pyplot モジュールをインポートした際、ファイルからデフォルト設定を読み込む。

import matplotlib.pyplot as plt

2. ヒストグラムを描画する。

plt.hist() を呼び出したとき、内部状態を確認し、現在設定されている Figure オブジェクト (current figure) が存在するかどうかチェックする。存在する場合、現在設定されている Axes オブジェクト (current axes) の Axes.hist() を呼び出す。
存在しない場合は、Figure 及び Axes オブジェクトを作成し、それぞれ current figure 及び current axes に設定する。
そして、current axes の Axes.hist() を呼び出す。

plt.hist(x, 100)

3.タイトルを設定する。

同様に current figure、current axes の存在をチェックし、存在する場合は、current axes の Axes.set_title() を呼び出す。存在しない場合は、Figure 及び Axes オブジェクトを作成し、それぞれ current figure 及び current axes に設定する。
そして、current axes の Axes.set_title() を呼び出す。

plt.title(r'Normal distribution with $\mu=0, \sigma=1$')

4. 出力する。

内部状態にある Figure オブジェクトをすべて描画する。
user interface backend の場合はウィンドウが表示され、hardcopy backend の場合はファイルに出力される。

plt.show()