Python

home

> matplotlib詳細設定

【Python】matplotlib詳細設定

Pythonのmatplotlibでグラフを描画する方法を解説する。

データの読み込み

まず初めに、プロットしたいのデータの読み込みについて解説する。 Python上でデータ配列を作成してもプロットはできるが、大抵の場合はデータファイルからの読み込みをしたいと思う。 今回はサンプルとして下のようなデータファイルを用意した。

sample.dat

# x sin(x) cos(x) 1.0 0.8414709848078965 0.5403023058681398 2.0 0.9092974268256817 -0.4161468365471424 3.0 0.1411200080598672 -0.9899924966004454 省略 100.0 -0.5063656411097588 0.8623188722876839

このテキストファイルを読み込むにはnumpy.loadtxt()を用いる。 この時、3列のデータそれぞれの配列を確保したいのでunpack=Trueを指定し、先頭のコメント行を読み飛ばすためにskiprows=1とする。

オプション 説明
unpack 配列を展開する。戻り値はデータ列に対応する数となる。
skiprows データを読み飛ばす行数を指定。文字列等は読み込めないので基本的に読み飛ばす。
delimiter 区切り文字の指定。カンマ区切りの場合などで使える。
import numpy as np
x, y1, y2 = np.loadtxt("sample.dat", unpack=True, skiprows=1)

また、同様の操作ができるものとして配列の転置を利用する方法がある。 unpackを指定しない通常の方法であると[x, y1, y2]が対応する次のような配列が作成される。

array([[ 1.00000000e+00,  8.41470985e-01,  5.40302306e-01],
       [ 2.00000000e+00,  9.09297427e-01, -4.16146837e-01],
       [ 3.00000000e+00,  1.41120008e-01, -9.89992497e-01],
       [ 4.00000000e+00, -7.56802495e-01, -6.53643621e-01],
       [ 5.00000000e+00, -9.58924275e-01,  2.83662185e-01],
       省略
       [ 1.00000000e+02, -5.06365641e-01,  8.62318872e-01]]) 

このNumpy配列の転置をとると、データを列ごとにまとめることができる。

# 転置結果
array([[ 1.00000000e+00,  2.00000000e+00,  3.00000000e+00,
         4.00000000e+00,  5.00000000e+00,
         省略
         1.00000000e+02],
       [ 8.41470985e-01,  9.09297427e-01,  1.41120008e-01,
        -7.56802495e-01, -9.58924275e-01,
        省略
        -5.06365641e-01],
       [ 5.40302306e-01, -4.16146837e-01, -9.89992497e-01,
        -6.53643621e-01,  2.83662185e-01,
       省略
         8.62318872e-01]])

この方法では戻り値が1つの値のみでよくなるので、データの拡張性があると言える。 unpackでの方法を再現すると以下の通り。

# 戻り値は1つの値
data = np.loadtxt("sample.dat", skiprows=1)
# 転置
data_T = data.T
# データの取り出し
x = data_T[0]
y1 = data_T[1]
y2 = data_T[2]

以上でデータの読み込みは完了である。 ここからはこのデータを使用して解説を行う。
(追記)データが粗かったので、サンプル数を1000まで増やした。

グラフのレイアウト

Figureオブジェクトの生成

グラフの描画のために、グラフのフレームとなるFigureオブジェクトを生成する。 Figureオブジェクトはplt.figure()で生成する。

plot1.1.py

# matplotlibのインポート import matplotlib.pyplot as plt # Figureオブジェクトの生成(fig) fig = plt.figure()

実行しても何も表示されないが、グラフのフレーム(領域)を作成することができた。 ここからAxesオブジェクトを追加し、グラフの軸などを表示する。

Axesオブジェクトの生成

Axesオブジェクトはグラフの描画領域を決定し、軸や目盛などを表示する。 Figure.add_subplot()として生成する。

plot1.2.py

# Axesオブジェクトの生成(ax) ax = fig.add_subplot(111)

実行するとグラフの軸と目盛が現れる。これから軸や目盛の設定はこのAxesオブジェクトに対して行う。

plot1.2

複数のグラフの描画

先ほどAxesオブジェクトを生成したが、Figure.add_subplot()に数字の引数を与えることで複数のグラフを描画できる。 以下の例は横に3つのグラフを並べる場合である。

plot1.3.py

# 複数のAxesオブジェクトの生成 ax1 = fig.add_subplot(131) ax2 = fig.add_subplot(132) ax3 = fig.add_subplot(133)

3つの数字はそれぞれ、縦に並べるグラフの数、横に並べるグラフの数、何番目のグラフとするかに対応している。 例えばax2であれば、1行3列のグラフの2番目を担当している。 この数字が10を超える場合は(2,5,10)のようにカンマ区切りとする。

plot1.3

図全体の大きさと隣り合うグラフの間隔

図全体の大きさ(Figureオブジェクトの大きさ)はplt.figure()に引数を与えることで行う。 数値はインチで設定する。

# 図の大きさを横:縦=16:12(インチ)にする
fig = plt.figure(figsize=(16, 12))

隣り合うグラフの間隔はplt.subplots_adjust()を使用して設定する。 縦・横どちらの間隔も調整することが可能。

# 縦・横のグラフ間隔を指定
plt.subplots_adjust(wspace=0.3, hspace=0.3)

また、これらの設定は様々なグラフで共通であることが多いので、plt.rcParamsでデフォルト指定をしておくこともできる。

plt.rcParams["figure.figsize"] = [16.0, 12.0]  # [width(inch):height(inch)]
plt.rcParams["figure.subplot.wspace"] = 0.30   # padding-width-space
plt.rcParams["figure.subplot.hspace"] = 0.30   # padding-height-space

図の余白の設定

これもplt.rcParamsで指定するのがよい。 図の上下左右の余白を指定でき、その内側でAxesオブジェクトを生成する。

plt.rcParams["figure.subplot.left"] = 0.14     # padding-left
plt.rcParams["figure.subplot.bottom"] = 0.14   # padding-bottom
plt.rcParams["figure.subplot.right"] = 0.90    # padding-right
plt.rcParams["figure.subplot.top"] = 0.91      # padding-top

グラフの種類

折れ線グラフ

折れ線グラフはAxes.plot()で描画する。 第一引数と第二引数に指定した配列を元にグラフを作成する。 第一引数は省略可能で、省略すると[0, 1, 2, ..., N-1]として扱われる。

オプション 説明
label プロットのラベル。凡例に表示される。
color 折れ線の色。cでも可。
dashes 折れ線の実線部分と空白部分の長さをリストで指定。
linestyle 折れ線の線種。lsでも可。dashesが指定されていると無効。
linewidth 折れ線の太さ。lwでも可。
alpha 透明度を0〜1で指定。
zorder オブジェクトが重なっていた時、この値が大きい方が前面に描画される。
marker マーカーの形状。Noneでマーカーなし。
markersize マーカーのサイズ。msでも可。
markerfacecolor マーカーの色。mfcでも可。
markeredgecolor マーカーの縁の色。mecでも可。
markeredgewidth マーカーの縁の太さ。mewでも可。

以下、実行例を載せる。fmtの形式では[color][marker][linestyle]をまとめて記述できる。

# axはAxesオブジェクト
ax.plot(x, y1, label='line_1')
ax.plot(y2, color='green', marker='o', linewidth=2, markersize='12', label='line_2')
# fmtで指定
ax.plot(x, y3, 'go-', label='line_3')

sample.datのデータを用いて、今回は次のように指定してみた。

plot2.1.py

ax.plot(x, y1, color='green', linewidth=3, label='sin(x)') ax.plot(x, y2, 'yo-', label='yellow')
plot2.1

また、2つのデータを別々のグラフとして描画することもできる。

plot2.2.py

ax1 = fig.add_subplot(211) ax2 = fig.add_subplot(212) ax1.plot(x, y1, color='green', linewidth=3, label='sin(x)') ax2.plot(x, y2, color='blue', linewidth=3, label='cos(x)')
plot2.2

散布図

散布図はAxes.scatter()で描画する。 基本的な設定は折れ線グラフと同様であるが、一部が異なるので表にまとめておく。

オプション 説明
s マーカーのサイズ。
c マーカーの色。facecolorfacecolorsでも可。
linewidths マーカーの縁の色。全て同じ場合はlinewidthlwでも可。
edgecolors マーカーの縁の色。デフォルトはcと同じ色。
ax.scatter(x, y, marker='o')

棒グラフ

棒グラフはAxes.bar()でプロットする。 エラーバー付きの棒グラフの場合はAxes.errorbar()でプロットする。 この時、エラーの大きさはデータ数と同じ長さの配列として用意する必要がある。

Axes.bar()オプション 説明
width 棒の幅(太さ)。横軸の値で指定する。
color 棒の色。facecolorfcでも可。
linewidth 棒の縁の太さ。lwでも可。
edgecolor 棒の縁の色。ecでも可。
Axes.errorbar()オプション 説明
xerr x軸方向のエラーバーの値または配列
yerr y軸方向のエラーバーの値または配列
capsize エラーバーの傘のサイズ。

今回はsample.datを利用して、-1から1までのデータ数に関してヒストグラムを作成してみた。

plot2.3.py

ax.bar(x, height, color='green', label='sin(x)', width='0.05')
plot2.3

軸まわりの設定

軸ラベル

グラフの軸ラベルはAxes.set_xlabel()Axes.set_ylabelで設定する。 第一引数にラベルの文字列を指定する。文字のスタイルは文字の設定でのパラメータを使用できる。

縦軸と横軸のラベル名を同時に設定する場合はAxes.set(xlabel='横軸ラベル名', ylabel='縦軸ラベル名')またはAxes.update(dict(xlabel='横軸ラベル名', ylabel='縦軸ラベル名'))と一行で書ける。 また、Axesオブジェクト生成時にラベルを指定する方法もある。

引数 説明
fontsize ラベルの文字のフォントサイズ。
color ラベルの文字の色。
labelpad ラベルの文字と軸の間隔。デフォルトはNone
loc ラベルの位置。デフォルトはcenter
# xとyそれぞれを設定する
ax.set_xlabel('xLabel', fontsize=15, color='black')
ax.set_ylabel('yLabel', labelpad=25, fontsize=15, color='blue')
# xとy同時に設定する
ax.set(xlabel='xLabel', ylabel='yLabel')
# Axesオブジェクト生成時に設定する
ax = fig.add_subplot(111, xlabel='xLabel', ylabel='yLabel')

sample.datの例では次のように設定した。

plot3.1.py

ax1.set_ylabel('Amplitude') ax2.set_xlabel('Time (s)') ax2.set_ylabel('Amplitude')
plot3.1

また、複数のグラフにおいて、軸ラベルの位置を揃える時はFigure.align_labels()を用いる。

# 複数のグラフで軸ラベルの位置を揃える 
fig = plt.figure()
fig.align_labels()
# 横軸ラベル・縦軸ラベルだけに設定
fig.align_xlabels()
fig.align_ylabels()
# 特定のグラフにのみ設定   
fig.align_labels([ax1, ax2])

軸ラベルに関してもplt.rcParamsでデフォルトの設定をしておくのがよい。

plt.rcParams["axes.labelsize"] = 24
plt.rcParams["axes.labelpad"] = 20

軸の範囲

軸の範囲(最大値・最小値)はAxes.set_xlim()またはAxes.set_ylim()で設定する。 それぞれには最大値・最小値の値を与える。 縦軸と横軸の最小値・最大値を同時に設定する場合はAxes.set(xlim=(left, right), ylim=(bottom, top))と一行で書ける。 軸ラベルと同様に、Axesオブジェクト作成時にxlimylimで指定することもできる。

ax1.set_xlim(-20, 20)
ax.set_ylim(0, 100)
# xとy同時に設定する
ax.set(xlim=(-20, 20), ylim=(0, 100))
# Axesオブジェクト生成時に設定する
ax = fig.add_subplot(111, xlim=(-20, 20), ylim=(0, 100))

sample.datの例では次のように設定した。

plot3.2.py

ax1.set_ylim(-1.5, 1.5) ax2.set_ylim(-1.5, 1.5)
plot3.2

軸の範囲の余白

軸の範囲を設定していない場合、データの最大値と最小値から外側に一定の余白が自動で設定される。 この余白の大きさはデフォルトで0.5に設定されているが、plt.margins()で変更することができる。 また、Axesオブジェクト生成時にxmarginymarginで与えることもできる。

# デフォルト(margin=0.05)
# margin=0として余白をなくす
ax = fig.add_subplot(111, xmargin=0, ymargin=0)
# plt.marginsで指定
plt.margins(0.08)
plt.margins(0, 0.05)    # (xmargin, ymargin)

軸線・グリッド線の設定

軸線・グリッド線はplt.rcParamsで記述しておくのがよい。 線の太さやグリッド線の有無、線種などを設定できる。

plt.rcParams["axes.linewidth"] = 1.5      # 軸線の太さ
plt.rcParams["axes.grid"] = False         # グリッド線の有無
# axes.gridをTrueとした場合に有効
plt.rcParams["grid.color"] = "black"      # グリッド線の色
plt.rcParams["grid.linestyle"] = "--"     # グリッド線の線種
plt.rcParams["grid.linewidth"] = 1.0      # グリッド線の太さ

目盛の設定

軸の目盛には主目盛と補助目盛があり、主目盛には目盛ラベルがついている。

目盛ラベルの間隔の設定

目盛ラベルの間隔はAxes.set_xticks()またはAxes.set_yticks()で設定する。 引数には目盛ラベルに設定したい数値の配列を渡す。 目盛ラベルに対応して主目盛が決定され、補助目盛もそれに合わせて変更される。

ax.set_xticks([-5.0, -2.5, 0, 2.5, 5.0])
ax.set_ylabel([0, 20, 40, 60, 80, 100])

sample.datの例では次のように設定した。

plot4.1.py

# 目盛ラベルの配列を生成する ticks = np.linspace(-1.0, 1.0, 3) ax1.set_yticks(ticks) ax2.set_yticks(ticks)
plot4.1

軸の目盛はAxis.set_major_locator()(主目盛)またはAxis.set_minor_locator()(補助目盛)にMultipleLocatorを渡すことでも変更できる。 デフォルトでは主目盛はAutoLocator、補助目盛はNullLocatorになっているので、Locatorを変更する必要がある。 Locatorはmatplotlib.ticker.XXXLocater()で作成することができ、これを先の関数に渡す。

# モジュールをインポート
import matplotlib as mpl
# 主目盛と補助目盛の間隔を変更 
ax.xaxis.set_major_locator(mpl.ticker.MultipleLocator(2))      # x軸主目盛の間隔2 
ax.xaxis.set_minor_locator(mpl.ticker.MultipleLocator(0.5))    # x軸補助目盛の間隔0.5 
ax.yaxis.set_major_locator(mpl.ticker.MultipleLocator(0.5))    # y軸主目盛の間隔0.5 
ax.yaxis.set_minor_locator(mpl.ticker.MultipleLocator(0.25))   # y軸補助目盛の間隔0.25 

今回、LocatorはMultipleLocatorを使用しているが、この他にも次のようなものがある。

Locator 説明
NullLocator 目盛なし(ラベルもなし)。使用時はax.set_xticks([])を使う方が簡単。
AutoLocator 自動で目盛を設定。主目盛のデフォルトとなっている。
MultipleLocator 特定の値の整数倍に目盛を設定。
IndexLocator 等差数列の目盛を設定。
IndexLocator(base, offset)とすると「base * n + offset」の位置に目盛を設定する。
LinearLocator LinearLocator(numticks)
とする。 グラフ最小値・最大値の間を「numticks - 1」等分する位置に目盛を設定。

目盛の詳細設定

目盛と目盛ラベルの詳細設定はAxes.tick_params()にオプションを指定して行う。

オプション 指定可能な値 説明
axis x, y, both 目盛を設定する軸。デフォルトはboth
which major, minor, both 主目盛と補助目盛の選択。デフォルトはmajor
direction in, out, inout 目盛の方向。デフォルトはout
length 数値 目盛の長さ。
width 数値 目盛の幅。
color 色名またはカラーコード 目盛の色。
pad 数値 目盛と目盛ラベルの距離。
labelsize 数値 目盛ラベルのサイズ。
labelcolor 色名またはカラーコード 目盛ラベルの色。
colors 色名またはカラーコード 目盛と目盛ラベルの色を同時に変更。
bottom
top
left
right
bool型 目盛の表示の有無。
labelbottom
labeltop
labelleft
labelright
bool型 目盛ラベルの表示の有無。

目盛と目盛ラベルの詳細設定についてはplt.rcParamsでデフォルト指定をしておくことが多い。

# 目盛の有無
plt.rcParams["xtick.top"] = True
plt.rcParams["xtick.bottom"] = True
plt.rcParams["ytick.left"] = True
plt.rcParams["ytick.right"] = True
# 目盛の方向
plt.rcParams["xtick.direction"] = "in"
plt.rcParams["ytick.direction"] = "in"
# 補助目盛の有無
plt.rcParams["xtick.minor.visible"] = True
plt.rcParams["ytick.minor.visible"] = True
# 目盛の幅
plt.rcParams["xtick.major.width"] = 1.5
plt.rcParams["ytick.major.width"] = 1.5
plt.rcParams["xtick.minor.width"] = 1.0
plt.rcParams["ytick.minor.width"] = 1.0
# 目盛の長さ
plt.rcParams["xtick.major.size"] = 10
plt.rcParams["ytick.major.size"] = 10
plt.rcParams["xtick.minor.size"] = 5
plt.rcParams["ytick.minor.size"] = 5

凡例の設定

凡例はAxes.legend()で設定することができる。 グラフのプロット時にlabelオプションでラベルを指定しておく必要があり、その文字列を使用して凡例が作成される。 Axes.legend()のオプションでよく使うものをまとめた。

オプション 説明
loc 凡例の位置。デフォルトはbest
frameon 凡例の枠の有無。bool型で指定する。
borderaxespad 凡例と軸との間の余白。指定した数値分の余白を全方向に確保する。
fontsize 凡例の文字のフォントサイズ。
markerscale 凡例でのマーカーの大きさ。
facecolor 凡例ボックスの背景色。
edgecolor 凡例ボックスの縁の色。

sample.datで凡例の設定例を示す。

plot5.1.py

ax1.legend(loc='upper right', frameon=True, borderaxespad=1) ax2.legend(loc='upper right', frameon=True, borderaxespad=1)
plot5.1

これにてグラフの詳細設定は一通り完了した。 だいぶ見栄えのよいグラフになったのではないだろうか。

凡例の設定についてもplt.rcParamsで記述しておこう。


plt.rcParams["legend.loc"] = "best"
plt.rcParams["legend.frameon"] = False
plt.rcParams["legend.fontsize"] = 20
plt.rcParams["legend.borderaxespad"] = 1.0
plt.rcParams["legend.facecolor"] = "white"
plt.rcParams["legend.edgecolor"] = "black"
# 凡例の枠を丸角にする
plt.rcParams["legend.fancybox"] = False
# plt.rcParams["legend.markerscale"] = 2

グラフの保存

グラフの保存はplt.savefig()で行う。 引数には保存するグラフのファイル名を指定し、dpiオプションで解像度を設定できる。 plt.show()では表示するだけなのでしっかりと保存しておこう。

plt.savefig('sample.png', dpi=300)

文字の設定

フォントとサイズ

文字のフォントは全体で統一するためplt.rcParamsに記述する。 また、文字サイズのデフォルト値も同時に指定するとよい。


plt.rcParams["font.family"] = "serif"
plt.rcParams["font.serif"] = "Times New Roman"
デフォルトの文字サイズ
plt.rcParams["font.size"] = 18

上付き文字・下付き文字

上付き文字・下付き文字は書式$^{}$$_{}$を用いる。 次の例を参考にしてほしい。

# ラベルに'y = x2'と書きたい(上付き)
label='$y = x^{2}$'
# ラベルに'Time, ti'と書きたい(下付き)
label='Time, $t_{i}$'

なお、この書式では文字が斜体となるため、これを修正する場合は\mathregular{}を記述する。 また、$\it{}$を使用すると、斜体を宣言することができる。

# 斜体の修正
label='Wavenumber ($\mathregular{cm^{-1}}$)'

ギリシャ文字

ギリシャ文字を使用するには$$の中にその文字を表す単語を記述する。 大文字と小文字の区別は、記述する単語の先頭に合わせて決定される。 一部の文字は先頭のアルファベットが意味を持ってしまうので、エスケープが必要である。

# デルタ(大文字と小文字)
label='$\Delta$'    # Δ
label='$\delta$'    # δ
# \tは意味を持つのでrを用いてエスケープ
label=r'Angle $\theta$'     # Angle θ

また、ギリシャ文字以外の特殊文字も類似の方法で使用できる。

# オングストローム
label='Distance [$\mathregular{\mathring{A}$]'    # Distance [Å]
PREVIOUS TOP

NEXT