Help us understand the problem. What is going on with this article?

matplotlib逆引きメモ(フレーム編)

matplotlibには、同じことをやるのに複数の方法が存在します。そのため、やりたいことを実現する手段を見つけにくいという難点があります。筆者は、せっかく見つけた方法をすぐに忘れてしまうため、目的からその実現方法を探しだせるようなメモを残しておくことにしました。

長くなりますので、テーマごとに別記事にします。初回は、グラフの枠の設定やデフォルトパラメータなど基礎的な部分です。以降、他のテーマを続けて書いていきますので、リストや図の番号は「X-Y」のように名付けます。Xは記事番号、Yは記事内番号です。

なお、クラスやメソッドなど必要な語句は、公式サイトの当該項目へのリンクを設定しています。参考にしてください。結果の出力や検証に用いたシステムは、matplotlibは2.2.2、numpyは1.14.3、Pythonは3.5.3、OSはDebian9.4です。

逆引きメモ

1-1. 同じことをやるのに、全く違うコードがあるのはどうして?

matplotlibには、大きく分けて、

  1. pyplotモジュールのメソッドのみを使用する方法
  2. オブジェクト(特にFigureとAxes)を使用する方法

があります。そのため、ネット上のサンプルにも様々な実現方法が示されており、混乱の原因になります。

ここでは、pyplotのメソッドを直接に使用することは出来るだけ避け、主としてオブジェクトを利用することにします。

1-2. いちばん簡単なグラフは?

リスト1-1
01 import matplotlib.pyplot as plt
02
03 fig, ax = plt.subplots()
04 plt.show()

いちばん簡単なグラフは、何もないグラフです。グラフの枠だけを描きます。OSによって違いますが、図1-1のようなウィンドウが新しく作成されます。赤点線と青点線は説明のために後で付け加えたものです。

図1-1 枠線だけのグラフ

3行目でFigureクラスとAxesクラスのインスタンスを同時に作成しています。

1-3. pltて何?

matplotlibパッケージのpyplotモジュールの別名です。リスト1-1の1行目の書式でimportします。pltという名前は単なる習慣ですが、公式サイトを含め、ほとんど全てのプログラム例で、pltを別名にしています。公式サイトの解説文の中でさえ、matplotlib.pyplot.XXXと記述する代わりに、plt.XXXと書いていることもあります(この記事でも、この省略法を用います)。これ以降のプログラムリストでは、このimport文を省略することがあります。pltという名前が出てきたら、このimport文が冒頭にあるものとみなしてください。

1-4. Figureて何?

Figureは、図1の赤点枠の中を描画するクラスです。印刷の場合の用紙に相当します。通常は、plt.subplotのようなメソッドで作成するので、Figureという名前が表にでることはありませんが、どんなメソッドがあるか覚えておくと便利です。

Figureのインスタンスは、「fig」という名前にすることが多いようです。

1-5. Axesて何?

Axesは、1個のグラフを統括するクラスです。図1の青点枠を描画します。目盛や軸タイトルなど枠の外側への描画にも関係します。Figureと同様、Axesと言う名前が表に出ることは、ほとんどありません。

1個のFigureは複数のAxesを持つことができます。Axesのインスタンスは、1個の場合は「ax」、2個以上の場合は「ax1」、「ax2」などと名付ける習慣があります。

1-6. plt.showは、何をしているの?

全ての描画作業が終了したあとに、plt.show()を実行して、ウィンドウを表示します。これを書くのを忘れると、画面に何も表示されません。これは図をスクリーン上に表示するために必須のメソッドであるため、以降のプログラムリスト中では、plt.show()を省略する場合があります。

1-7. ディスプレイ上に描画される図のサイズを知りたい

バージョン2.0以降のデフォルト値は、ピクセル単位で640x480です(図1の赤点枠のサイズ)。

1-8. 図のサイズを指定したい

例えば、横幅を800ピクセル、高さを600ピクセルにしたい場合、リスト1-2のように2段階でインスタンスを作成します。

リスト1-2
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8.0, 6.0))
ax = fig.add_subplot(111)
plt.show()

1-9. plt.figureは何をしているの?

plt.figureはFigureクラスのインスタンスを作成するメソッドです。各種のキーワードを使って、Figureクラスのパラメータを設定することができます。

1-10. figsizeキーワードの意味は?

figsizeキーワードを使って、図の横幅と高さ(図1の赤点枠)をインチ単位で指定することができます。タプルで指定します。指定しなかった場合は、デフォルト値の(6.4, 4.8)が採用されます。

1-11. インチ単位とピクセル単位の関係は?

インチ単位をピクセル単位にするにはdpiパラメータの値が必要ですが、dpiのデフォルト値は100です。リスト1-2の例なら、横幅 = 8.0x100 = 800ピクセル、高さ = 6.0x100 = 600ピクセルになります。

1-12. fig.add_subplotの引数(111)の意味は何?

Figureクラスのadd_subplotメソッドは、Axesクラスのインスタンスを作成します。

Figureクラスは複数のAxesを持つ場合、グラフをグリッド状に配置します。add_subplotの引数は、グラフの識別番号で、3桁の整数です。それを(RCP)とした時、Rはグリッドの行数、Cはグリッドの列数、Pはグリッドにおけるグラフの順番です。順番は1から始まり行優先です。R=2、C=3の場合、図1-2のように識別番号が来まります。

図1-2 グラフの識別番号

なお、図1-2を描いたプログラムはリスト1-3です。

リスト1-3
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(6.0, 4.0))
c = 1
for row in range(1,3):
    for col in range(1,4):
        id = 230 + c
        ax = fig.add_subplot(id)
        ax.set_title(id)
        ax.tick_params(labelbottom=False, labelleft=False, direction='in')
        c = c + 1

plt.savefig('fig02.png', facecolor='#cccccc')

1-13. 図の中のグラフの位置や大きさを変更したい

図1-3 グラフの位置と大きさを変更する

図3のように、横に細長い図の右側にグラフ枠を描画するには、リスト1-4のように、リスト1-2に1行加えます。

リスト1-4
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(6.0, 3.0))
ax = fig.add_subplot(111)
ax.set_position([0.5,0.1,0.4,0.8])
plt.show()

ここで、ax.set_positionの引数は要素4個のリスト(またはタプル)で、枠の座標を指定します。

ax.set_position([枠の左辺, 枠の下辺, 枠の横幅, 枠の高さ])

4個の値は全て、実座標ではなく割合です。左右のサイズ(枠の左辺、枠の横幅)には図の横幅を基準に取り、上下のサイズ(枠の下辺、枠の高さ)には図の高さが基準になります。例えば、枠の横幅をピクセルに換算すると、以下のように、240ピクセルになります。

グラフ枠の横幅(ピクセル)
    = 図の横幅(インチ) x DPI x グラフ枠の横幅(割合)
    = 6.0 x 100 x 0.4 = 240

ところで、リスト1-4はリスト1-5のようにすれば、実質2行ですますことができます。add_axesもAxesインスタンスを作成します。グラフが1個であり、グラフ枠を指定するときには、add_axesが簡単です。

リスト1-5
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(6.0, 3.0))
ax = fig.add_axes([0.5,0.1,0.4,0.8])
plt.show()

1-14. デフォルト値を知りたい

リスト1-6
import matplotlib as mpl

print(mpl.matplotlib_fname())

matplotlibでは、各種のパラメータのデフォルト値が定められています。システムに最初から格納されているファイルのパスは、リスト1-6のように、matplotlib_fnameで知ることができます。デフォルト値を示すファイルは、matplotlibrcという名前です。

Debian10.0でpipを使ってインストールした場合、システムのmatplotlibrcのパスは下記です。

/usr/local/lib/python3.7/dist-packages/matplotlib/mpl-data/matplotlibrc

このファイルの一部をリスト1-7に示します。上に述べたように、figsizeのデフォルト値は(6.4, 4.8)、dpiのデフォルト値が100になっていることが分かります。システムのmatplotlibrcでは、backend以外のパラメータが全てコメントアウトされています。変更する場合は、当該行をアンコメントして、値を変更します。

リスト1-7
(省略)
backend      : TkAgg
(省略)
#### FIGURE
## See http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure
#figure.titlesize : large      ## size of the figure title (Figure.suptitle())
#figure.titleweight : normal   ## weight of the figure title
#figure.figsize   : 6.4, 4.8   ## figure size in inches
#figure.dpi       : 100        ## figure dots per inch
#figure.facecolor : w      ## figure facecolor; 0.75 is scalar gray
#figure.edgecolor : w      ## figure edgecolor
#figure.frameon : True          ## enable figure frame
#figure.max_open_warning : 20  ## The maximum number of figures to open through
                               ## the pyplot interface before emitting a warning.
                               ## If less than one this feature is disabled.
## The figure subplot parameters.  All dimensions are a fraction of the
#figure.subplot.left    : 0.125  ## the left side of the subplots of the figure
#figure.subplot.right   : 0.9    ## the right side of the subplots of the figure
#figure.subplot.bottom  : 0.11   ## the bottom of the subplots of the figure
#figure.subplot.top     : 0.88   ## the top of the subplots of the figure

なお、matplotlib_fnameは、matplotlib直属のメソッドです。mplは、matplotlibの別名として習慣的な名前です。このimport文も、これ以降省略する場合があります。

1-15. デフォルト値を変更したい

あなたが管理者であれば、システムのmatplotlibrcを変更しても構いませんが、一般ユーザである場合は、システムのmatplotlibrcを、ユーザ専用のconfigディレクトリにおき、リスト1-7を参考にデフォルト値を変更してください。リスト1-8に例をあげます。backendパラメータが設定されていないと、何も出力されなくなるので注意してください。

リスト1-8
backend: TkAgg
figure.figsize: 8.0, 6.0

ユーザ専用のconfigディレクトリのパスは、リスト9のように、get_configdirメソッドを使って知ることができます(「Customizing matplotlib」参照)。matplotlibrcは、カレントディレクトリに置いても有効です(カレントディレクトリに置かれたものが優先されます)。

リスト1-9
import matplotlib as mpl

print(mpl.get_configdir())

なお、専用のmatplotlibrcを設定すると、matplotlib_fname()の戻り値は、システムのmatplotlibrcではなく、新たに設定したmatplotlibrcを指します。

1-16. プログラム中でデフォルト値を変更したい

プログラム中でデフォルト値を変更することもできます。リスト1ー4と同じことを、デフォルト値を変更することで実現したのが、リスト1ー10です。

matplotlibのデフォルト値は、実行時にmpl.rcParamsに格納されます。rcParamsは、RcParamsクラスのインスタンスとして定義されていますが、辞書(dictionary)のように扱うことができます。

リスト1-10では、デフォルト値を変更するために、2種類の方法を使っています(あくまでも例です。実際には、こんなまわりくどいことはしません)。

リスト1-10
01 import matplotlib as mpl
02 import matplotlib.pyplot as plt
03
04 mpl.rcParams['figure.figsize'] = [6.0, 3.0]
05 mpl.rc('figure.subplot', left=0.5, right=0.9, bottom=0.1, top=0.9)
06 fig, ax = plt.subplots()
07 plt.show()

リスト1ー4において、figureメソッドでfigsizeを設定しています。これは、リスト1-7をみれば、figure.figsizeパラメータの変更に対応することが分かります。このパラメータはリストですので、4行目のようにリストとして代入します(タプルを代入しても可)。

リスト1-7のうち、figure.subplot.X (X = left, right, bottom, top...)は、グラフ枠を示す四角を決めます。ところで、このようなドットで継げた一連の変数をグループと呼びますが、グループの変数は5行目のように、mpl.rcメソッドを使って、一括して変更することができます。もちろん、5行目の代わりに、各パラメータを別々に変更してもかまいません。

リスト1-11
05 mpl.rcParams['figure.subplot.left'] = 0.5
06 mpl.rcParams['figure.subplot.right'] = 0.9
07 mpl.rcParams['figure.subplot.bottom'] = 0.1
08 mpl.rcParams['figure.subplot.top'] = 0.9

ところで、rcParamsパラメータとrcメソッドは、plt(matplotlib.pyplotの別名)からもコールできます。pltを使った方が面倒でなくていいかも知れません。

リスト1-12
04 plt.rc('figure',figsize=[6.0, 3.0])
05 plt.rc('figure.subplot', left=0.5, right=0.9, bottom=0.1, top=0.9)

1-17. 画像ファイルを作成したい

plt.show()はディスプレイに出力するメソッドですが、画像ファイルを作成したい場合、代わりにplt.savefig()メソッドを使います。出力ファイルの形式は、ファイル名の拡張子から決められます。デフォルトでは画面出力と同じ大きさの画像が作成されます。

リスト1-13
# リスト1ー10を変更して
07 plt.savefig('list1-13.png')

1-18. 印刷用に精細な画像ファイルがほしい

画像ファイルを印刷用として作成する場合、デフォルトのままではかなり小さな画像しか出来ません。それは、ディスプレイ画面とプリンタのdpiが異なるからです。ディスプレイ画面はディスプレイのサイズによりますが、dpi=100程度とみなすことができます。

印刷用の画像を作成するには、dpi引数でDPIを指定する必要があります。プリンタのDPIに合わせて決めると良いでしょう。dpiを省略した場合には、plt.figureで設定した値、それもなければデフォルト値のdpi=100になります。

リスト1-14
# リスト1ー10を変更して
07 plt.savefig('list1-14.png', dpi=600)

変更履歴

2020-02-06: 説明をわかりやすくするため、1-17を分割して1-18を付加しました

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away