LoginSignup
386
368

More than 3 years have passed since last update.

matplotlibの描画の基本 - figやらaxesやらがよくわからなくなった人向け

Posted at

matplotlibは、figureやsubplotなどなどがどう働いているのかが分かりにくい。
そこで、ここでは、matplotlibの描画の構造について説明する。

これ以降、matplotlib.pyplotをpltとしてimportしているとする。

import matplotlib.pyplot as plt

plt.figure()

plt.figure()が最初に出てくることが多い。figure()はFigureインスタンスを作成する。
Figureインスタンスは、描画全体の領域を確保する。
引数では以下を指定できる。

  • figsize: (width, height)のタプルを渡す。単位はインチ。
  • dpi: 1インチあたりのドット数。
  • facecolor: 背景色
  • edgecolor: 枠線の色

plt.figure()では描画領域の確保だけなので、グラフは何も描画されない。

fig.add_subplot()

plt.figure()にグラフを描画するためにsubplotを追加する必要がある。
subplotの追加は、add_subplotメソッドを使用する。

fig = plt.figure()
fig.add_subplot(111)

これで以下のように軸などのグラフの描画領域が追加される。

subplot111.png

111の意味は、1行目1列の1番目という意味で、subplot(1,1,1)でも同じである。
subplotはAxesオブジェクトを返す。
Axesは、グラフの描画、軸のメモリ、ラベルの設定などを請け負う。

add_subplotは基本的に上書きとなる。以下は、どういう構成化わかりすくするために、わざと上書きしたもの。

fig = plt.figure()
fig.add_subplot(1, 1, 1)
fig.add_subplot(3, 3, 1)   # 3x3の1つめ(左上)
fig.add_subplot(3, 3, 3)   # 3x3の3つめ(右上)
fig.add_subplot(3, 3, 8)   # 3x3の8つめ(真ん中下)

overdraw_graphs.png

plt.subplot()

plt.subplot()はadd_subplotと同様に、引数に行数列数及び何番目かを指定できる。
add_subplotとの違いは、現在の描画領域(fig = figure()のこと)に追加するメソッドであるということ。
あまりないと思うが、figure()を何個も立ち上げてるときに、どれを操作しているかわかりにくくなる。

plt.subplot(3,3,1)
plt.subplot(3,3,3)
plt.subplot(3,3,5)
plt.subplot(3,3,9)

subplots.png

subplotはsubplot以前に描画していたfigureとかぶった場合、前のfigureを消す性質を持っている。

plt.plot([1,2,3])
plt.subplot(211)   # このタイミングで plt.plot([1,2,3]) は消されてしまう。
plt.plot(range(12))
plt.subplot(212)

plt.subplots()

plt.subplot()と似たものとしてplt.subplots()もある。
返り値はfigとAxesまたはAxesオブジェクトの配列。

plt.subplots()は実は、fig = figure()をした後、fig.add_subplot(111)した場合と同じである。
subplots()も、add_subplotの場合と同様にAxesオブジェクトを返す。

fig = plt.figure()
plt.add_subplot(111)

plt.subplots()の引数に行数列数を与えることで、複数のAxesオブジェクトを生成できる。

fig, axes= plt.subplots(2,2)   # axesはAxesオブジェクトの2x2の配列
axes[0][0].plot([1,2,3])
axes[1][0].plot([4,5,4,5])

上記スクリプトの出力結果は以下のようになる。

2x2subplots.png

Axes

Axesオブジェクトは、実際のデータの描画の役割を持っている。
Axesオブジェクトに対して描画するデータを与えたり、set_xlabel、set_ylabel、set_titleで
ラベルやタイトルの設定をできる。
また、同じAxesオブジェクトにplotを重ねることもできる。

ax1 = plt.subplot(2,2,1)   # 4x4の1番目
ax4 = plt.subplot(2,2,4)   # 4x4の4番目
ax1.plot([1,2,3,4])   # 1番目に描画
ax1.plot([2,3,2,3])   # 1番目に追加描画
ax1.set_xlabel('foo')   # 1番目にxラベルを追加
ax1.set_ylabel('bar')   # 1番目にyラベルを追加
ax4.plot([5,10,20,10])   # 4番目に描画
ax4.set_title('baz')   # 4番目にタイトルを追加

axes_sample.png

plt.title()、plt.xlabel()、plt.ylabel()

グラフを1つずつ描画しているときは、plt.title()、plt.xlabel()、plt.ylabel()をよく使うのだが、
結局これは何かというと、ax = subplot(111)にたいして、ax.set_title()、ax.set_xlabel()、ax.set_ylabel()
とやっていることと同じとなる。

plt.gcf()

figureをたくさん立ち上げているとどのfigureにいるかわからなくなることがある。
現在のfigureを確認するためにはplt.gcf()を使う。gcfはget current figureの略。
以下の例ではそれぞれplt.gcf()の出力結果が変わることが分かる。

fig1 = plt.figure()
print(plt.gcf().number)   # => 1
fig2 = plt.figure()
print(plt.gcf().number)   # => 2
plt.close()
print(plt.gcf().number)   # => 1

plt.gca()

plt.gcf()と似た関数でplt.gca()がある。
これは、現在のAxesオブジェクトを返す。
ax = subplot(111)でやらずにあとからAxesオブジェクトを変数に定義できる。

plt.subplot(111)
ax = plt.gca()
386
368
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
386
368