Pynote

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

matplotlib - matplotlib で指定した解像度の図を作る方法

figsize, dpi と出力される図の解像度の関係

  • figsize=(w_in, h_in): Figure の大きさ。インチ単位で指定する。
  • dpi: 1インチあたりのドット数。

figsize, dpi と生成された図の解像度 (w_px, h_px) は以下の関係が成り立つ。

w_{px} = w_{in} (inch) * dpi (px/inch)
h_{px} = h_{in} (inch) * dpi (px/inch)

figsize, dpi は Figure オブジェクトを作成する関数の引数で指定できる。
指定しない場合はデフォルト値が使用される。

import matplotlib as mpl
print('figure.figsize', mpl.rcParams['figure.figsize'])  # figure.figsize [6.0, 4.0]
print('figure.dpi', mpl.rcParams['figure.dpi'])  # figure.dpi 72.0

上記に従えば、例えば、解像度が (640px, 480px) の図を作成したい場合、以下のようにすればよい。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, np.pi * 4, 1000)
y = np.sin(x)

figsize_px = np.array([640, 480])
dpi = 100
figsize_inch = figsize_px / dpi
print('figsize', figsize_inch)  # figsize (6.4, 4.8)

fig, ax = plt.subplots(figsize=figsize_inch, dpi=dpi)
ax.plot(x, y)

# 図を画像として保存して、画像の大きさを確認する。
fig.savefig('figure.png')
img = plt.imread('figure.png')
print(img.shape)  # (480, 640, 4)

指定した解像度になっていることが確認できる。

Jupyter Notebook で inline で図を表示する場合

Jupyter Notebook で inline で図を表示する場合、設定が bbox_inches='tight' で上書きされてしまうので、以下のように無向にする必要がある。

%matplotlib inline
%config InlineBackend.print_figure_kwargs = {'bbox_inches': None}


ポイントと出力される図の解像度の関係

fontsize など matplotlib の一部のパラメータはポイント (pt) 単位で指定するようになっている。
1pt = 1/72インチであるので、x インチをポイントに換算するには x (inch) * 72 (pt/inch) とすればよい。

上記に従えば、例えば、figsize の横幅が6インチであるとき、長さ13の文字列をこの幅に収まるようにするには、以下のようにすればよい。

figsize の横幅が6インチをポイント単位にすると、 6 pt * 72 pt/inch = 432 pt である。
この空間を27文字分で使うので、1文字あたりのフォントサイズは 432 / 13 = 33.23 より 33 pt とすればよい。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, np.pi * 4, 1000)
y = np.sin(x)

text = 'This is title'

figsize = 6, 4
dpi = 100
fontsize = int(figsize[0] * 72 / len(text))
print(fontsize)  # 33

fig, ax = plt.subplots(figsize=figsize, dpi=dpi)
fig.suptitle(text, fontsize=fontsize)