こんな人にオススメ
matplotlib.pyplot
(plt
)でグラフを書いているけど、もっと見やすいようにグラフを改造したい!そしてそのグラフを一つのテンプレートとしてどこかで一括管理したい!
何かいい方法はない?
pythonでグラフ作成する際、
matplotlib.pyplot
、通称plt
を使用することが多いと思う。本記事ではこのplt
でのグラフ作成時に使用している「グラフ作成雛形」について紹介する。本記事のpython環境については以下。
- Python 3.9.2
- numpy 1.20.1
- matplotlib 3.3.4
雛形説明
執筆者が使用しているコードとその説明をする。
完成形
まずはいつも使用している雛形の設定内容を示す。これ以降の節でそれぞれのパーツごとに説明していく。なお、デフォルトの値が知りたい場合は、plt.rcParams
を出力すると確認できる。plt.rcParams
の型については後述。
'font.size': 20 'font.family': 'Times New Roman' 'mathtext.fontset': 'stix' "figure.figsize": [16, 8] 'figure.facecolor': (0, 0, 0, 0) 'axes.facecolor': (0, 0, 0, 0) 'savefig.facecolor': (0, 0, 0, 0) 'figure.subplot.left': 0.11 'figure.subplot.right': 0.90 'figure.subplot.top': 0.95 'figure.subplot.bottom': 0.08 'figure.subplot.hspace': 0.1 'savefig.format': 'pdf' 'xtick.direction': 'in' 'ytick.direction': 'in' "xtick.top": True "ytick.right": True 'xtick.minor.visible': True 'ytick.minor.visible': True 'legend.edgecolor': 'black' 'legend.facecolor': 'white'
フォント
フォントは次の3種類の設定を行なっている。
'font.size': 20 'font.family': 'Times New Roman' 'mathtext.fontset': 'stix'
それぞれ以下の操作に対応する。
- フォントサイズ=20(デフォルトは10)
- 基本フォント=Times New Roman(デフォルトはsans-serif)
- $\LaTeX$使用時のフォントはstix(デフォルトはdejavusans)
論文やプレゼンに使用する際に文字の大きさ(=フォントサイズ)が小さいと、担当教授からめちゃくちゃ指摘を喰らうので、フォントサイズは大きめに設定。
また、大学4年生の頃、pythonをはじめたての頃に$\LaTeX$を使用してグラフを書いたときにフォントが
- 通常フォント:柔らかめのフォント
- $\LaTeX$フォント;シャキンとしたフォント
で(当時はどのフォントとかは意識してなかったので、一体なんのフォントだったのかわからん)、一番フォントの雰囲気が近くなるTime New Romanとstixを選んだ記憶がある。今はその時の流れに乗ってそのまま継続している感じ。執筆者とpythonとの出会いについては以下参照。
-
-
【M天パ(めがてんぱ)自己紹介】変わって楽しいの繰り返し
続きを見る
グラフの枠組み
グラフの枠組みというと語弊があるかもしれないが、ザッというとグラフの背景とか余白とかそういうの。いい言葉が思いつかなかった。グラフの枠組みは次の9種類の設定を行なっている。
"figure.figsize": [16, 8] 'figure.facecolor': (0, 0, 0, 0) 'axes.facecolor': (0, 0, 0, 0) 'savefig.facecolor': (0, 0, 0, 0) 'figure.subplot.left': 0.11 'figure.subplot.right': 0.90 'figure.subplot.top': 0.95 'figure.subplot.bottom': 0.08 'figure.subplot.hspace': 0.1
それぞれ以下の操作に対応している。
- 表示されるグラフのデフォルトサイズ(デフォルトは横6.4×縦4.8)
- 軸や軸ラベルなどの位置する、plotされない領域の色(デフォルトはwhite)
- plotされる領域の背景色(デフォルトはwhite)
- 保存時のグラフ全体(plot部分もそうでない部分も)の背景色(デフォルトはauto。表示された時と同じ背景色に設定されるから特に指定しなくてもいいけど明示している)
- グラフの端から左右上下方向への余白(デフォルトはそれぞれ0.125, 0.9, 0.88, 0.11)
- グラフを2枚同時に縦に並べた時の余白(デフォルトは0.2)
色に関しては'red'
などのように名前で指定してもいい、'#ff0000'
のように16進数で指定してもいいし、上記のようにRGBA(R:Red、G:Green、B:Blue、A:Alpha(透明度))で指定してもいい。
RGBA=(0, 0, 0, 0)と、グラフの背景を透明にしているのはPowerPointなどのスライドに貼り付けるときに便利だから。2つの別々のグラフを重ねる際に背景が透明でないと被って消えるか、手前側のグラフの透明度をいじらないといけない。前者だとそもそも重なって奥の画像が確認できないし、後者の場合はplotまで透明っぽくになってしまう。プレゼンソフトで透過させてもいいが、わざわざするくらいなら初めからするスタイル。
保存形式
作成したグラフはpngだったりpdfに保存することが多いと思うが、そのデフォルトの形式を選択できる。デフォルトはpng。論文やレポートなどのしっかり目の文書作成時に$\LaTeX$を使用するのでpdfにしている。
'savefig.format': 'pdf'
軸目盛の向き
作成したグラフの軸目盛は横軸、縦軸ともに内向きに設定。これは執筆者が大学生時代の実験のレポートに内向きにしなさいとの指示があった名残。実験のTAをする際に提出するTA用の実験レポートも内向きにするので、統一感のために全グラフに設定。
また、横軸の場合は下だけではなく上にも、縦軸の場合は右にも軸目盛を追加した。これは自分が読む論文に出てくるグラフが大体そうしているから。あとは単純に他の研究室メンバーがしていないからの優越感。
'xtick.direction': 'in' 'ytick.direction': 'in' "xtick.top": True "ytick.right": True
それぞれが以下の操作に対応している。
- 横軸の目盛の向き(デフォルトは外向きのout)
- 縦軸の目盛の向き(デフォルトは外向きのout)
- 横軸の目盛をグラフの上部にも追加する(デフォルトはFalse)
- 縦軸の目盛をグラフの右部にも追加する(デフォルトはFalse)
副目盛
デフォルトでは主目盛のみの表示だが、副も欲しかったので追加。
'xtick.minor.visible': True 'ytick.minor.visible': True
それぞれが以下の操作に対応している。
- 横軸の副目盛を見えるようにする(追加する)(デフォルトはFalse)
- 縦軸の副目盛を見えるようにする(追加する)(デフォルトはFalse)
凡例のスタイル
凡例はなんとなくでこの色にした。
'legend.edgecolor': 'black' 'legend.facecolor': 'white' 'legend.framealpha': 1
それぞれが以下の操作に対応している。なお、前2つについてはinherit
を指定した場合はaxesのそれぞれに対応した色になる。
- 凡例の枠線の色(デフォルトは'0.8'。黒色がデフォルトで文字列の数字を入れると透明度を指定)
- 凡例の背景色(デフォルトは'inherit'。白色がデフォルト)
- 凡例の背景色の透明度(デフォルトは0.8)
デフォルト値変更方法
前章でコードの内容を示したので、実際のコードに落とし込む。
指定方法
plt
ではplt.rcParams
でデフォルトのグラフ設定をすることができる。このplt.rcParams
は辞書型になっているので以下の書き方で変更できる。
plt.rcParams['指定したい項目'] = 指定したい値
一旦上記のように変更してしまうと、pythonから抜け出すか設定を上書きしない限りは継続される。逆に言えば、新規でpythonを動かすときには毎回設定を変更しないといけない。まあ、根本の部分を下手に変更するよりかはいいだろう(根本の部分の変更の仕方は知らんし、そもそも出来るのかも知らん)。
ということで自分は一気に変更したいので以下のように設定している。
change_dct = { 'font.size': 20, 'font.family': 'Times New Roman', 'mathtext.fontset': 'stix', "figure.figsize": [16, 8], 'figure.facecolor': (0, 0, 0, 0), 'axes.facecolor': (0, 0, 0, 0), 'savefig.facecolor': (0, 0, 0, 0), 'figure.subplot.left': 0.11, 'figure.subplot.right': 0.90, 'figure.subplot.top': 0.95, 'figure.subplot.bottom': 0.08, 'figure.subplot.hspace': 0.1, 'savefig.format': 'pdf', 'xtick.direction': 'in', 'ytick.direction': 'in', "xtick.top": True, "ytick.right": True, 'xtick.minor.visible': True, 'ytick.minor.visible': True, 'legend.edgecolor': 'black', 'legend.facecolor': 'white', } for key, val in change_dct.items(): plt.rcParams[key] = val
辞書型のkeys
とvalues
をitems
で同時に回して、ループごとにplt.rcParams
を変更している。これで準備は整った。
実際にグラフ化
以上の設定を実装した前後のグラフを見て違いを確認する。今回使用した検証用コードは以下のもの。$\LaTeX$で表したグラフ凡例がすでにギリシャ文字になっているが、ここは\alpha
などと書いてほしい。
import numpy as np import matplotlib.pyplot as plt plt.ion() x = np.arange(-5, 5 + 1) y = x ** 2 def graph(name): """2次関数をグラフ化 Parameters ---------- name : str 作成したグラフの保存名 """ fig, ax = plt.subplots(1, 1) ax.set_title('title') ax.set_xlabel('x') ax.set_ylabel('y') ax.set_xlim(-6, 6) ax.set_ylim(-5, 30) ax.plot(x, y, 'o-', ms=4, label=r"$\alpha$") ax.plot(x, y + 2, 'o-', ms=4, label=r"$\beta$") ax.plot(x, y + 3, 'o-', ms=4, label=r"$\gamma$") ax.plot(x, y + 4, 'o-', ms=4, label=r"$\dagger$") ax.legend() ax.grid(which='major', ls='-') fig.savefig(f'plotly-base_plt_{name}.png') # この時点ではまだデフォルト設定 graph(name='before') change_dct = { 'font.size': 20, 'font.family': 'Times New Roman', 'mathtext.fontset': 'stix', "figure.figsize": [16, 8], 'figure.facecolor': (0, 0, 0, 0), 'axes.facecolor': (0, 0, 0, 0), 'savefig.facecolor': (0, 0, 0, 0), 'figure.subplot.left': 0.11, 'figure.subplot.right': 0.90, 'figure.subplot.top': 0.95, 'figure.subplot.bottom': 0.08, 'figure.subplot.hspace': 0.1, 'savefig.format': 'pdf', 'xtick.direction': 'in', 'ytick.direction': 'in', "xtick.top": True, "ytick.right": True, 'xtick.minor.visible': True, 'ytick.minor.visible': True, 'legend.edgecolor': 'black', 'legend.facecolor': 'white', 'legend.framealpha': 1, } # plt .rcParamsを変更 for key, val in change_dct.items(): plt.rcParams[key] = val # この時点ではデフォルトの値が変更されてる graph(name='after')
実装前
実装前、すなわちデフォルトの状態でのグラフは以下。
plt.rcParamsでデフォルトを変更する前のグラフ
まあ普通のグラフ。背景は白で目盛は外向きでフォントは柔らかめ。
実装後
実装後、すなわちデフォルトを変更した後のグラフは以下。
plt.rcParamsでデフォルトを変更した後のグラフ
グラフ自体の大きさが変わって、フォントもカッコよくなってる(主観的)。また、目盛は内向きで上下左右に配置されている。背景が透明かどうかは保存してみるとわかる。
好みあるよね
本記事で紹介したデフォルト変更方法はあくまでも一例。自分は図の大きさは16:9がいいとか、凡例も透過させたいとか色々あると思うからそこは各自で調整してくれたらいい。色々調節しまくるとどんどん迷走するので、時間があるときに一気に納得いくような雛形を作成してほしい。
これから当ブログで使用するplt
のグラフは基本的には前述の雛形に沿って作成していく。個人的にこの設定に慣れたから外観違うのは許して。