LoginSignup
7

More than 5 years have passed since last update.

matplotlibのfontsizeで指定する相対サイズの定義と利便性

Last updated at Posted at 2019-02-12

fontsizeオプション

matplotlibを用いた描画において,labelやtitle,ticklabelなどの文字の大きさはfontsizeオプションによって指定できる.これら文字に関連する要素のオプションは,matplotlib.text.Textクラスで定義されるものを引き継いでいる(公式リンク).
matplotlib.text.Textクラスにおいて定義される変数fontsizeは,point単位(約0.35278mm,1インチの72分の1)での絶対サイズ指定以外に,下記の相対サイズ指定ができる.

{'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'}

ソースコードの解説

これらは,デフォルトの文字サイズ(rcParams['font.size'])に対する倍率を表している.
具体的な値は,matplotlib.font_managerクラスのクラス変数で定義されている(ソースコード).

相対クラスの変換倍率(matplotlib.font_managerクラスのソースコードより)
font_scalings = {
    'xx-small' : 0.579,
    'x-small'  : 0.694,
    'small'    : 0.833,
    'medium'   : 1.0,
    'large'    : 1.200,
    'x-large'  : 1.440,
    'xx-large' : 1.728,
    'larger'   : 1.2,
    'smaller'  : 0.833,
    None       : 1.0}

これを,同クラスのset_size()において参照し,相対サイズを適用する.

set_size(matplotlib.font_managerクラスのソースコードより)
def set_size(self, size):
        #(中略)
        if size is None:
            size = rcParams['font.size']
        try:
            size = float(size)                # <--数字指定の場合
        except ValueError:
            try:
                scale = font_scalings[size]   # <--相対指定の場合
                                              #    font_scalingsから倍率取得
            except KeyError:
                raise ValueError(
                    "Size is invalid. Valid font size are "
                    + ", ".join(map(str, font_scalings)))
            else:  # <--try成功時 (相対指定)
                size = scale * FontManager.get_default_size() # defaultのsizeに倍率を乗じて使用
        if size < 1.0:
            _log.info('Fontsize %1.2f < 1.0 pt not allowed by FreeType. '
                      'Setting fontsize = 1 pt', size)
            size = 1.0
        self._size = size

図中の各パーツのデフォルト文字サイズ

matplotlib.rcParamsを参照すると,描画に必要なパラメータのデフォルト値の一覧を確認できる.そのうち,パーツごとの文字サイズに関するパラメータは下記のように確認できる(値は異なる可能性がある).

matplotlib.rcParamsの一部
'font.size': 10.0

'axes.titlesize': u'large'
'axes.labelsize': u'medium'
'legend.fontsize': u'medium'
'xtick.labelsize': u'medium'
'ytick.labelsize': u'medium'

上記のデフォルト値であり,かつfontsize指定をしなかった場合,タイトルは10.0×1.200=12pt,その他は10ptで描画が行われる.

図中の各パーツの文字サイズ確認

本当にそうなっているかを確認したい場合,各パーツに割り当てられているget_fontsize()メソッドを用いて実際に使用されている値を参照できる(代わりにset_fontsize(n)とすればfontsizeを変更することができる).

matplotlib.rcParamsの一部
# 適当に描画
fig = plt.figure()
ax  = fig.add_subplot()
ax.plot([0,1],[0,1],label='line_1')
ax.plot([0,1],[1,0],label='line_2')
ax.legend(title='legend')
ax.set_title('title')
ax.set_xlabel('x')
ax.set_ylabel('y')

# フォントサイズの取得
print ax.title.get_fontsize()
print ax.xaxis.label.get_fontsize()
print ax.yaxis.label.get_fontsize()
print ax.get_legend().get_title().get_fontsize()
### legendは,各プロットごとにパーツがわかれる
lgd_txts = ax.get_legend().get_texts()
print lgd_txts[0].get_fontsize()
### ticklabelは,各目盛ごとにパーツがわかれる
tcks = ax.xaxis.get_major_ticks()
print tcks[0].label.get_fontsize()

おわりに

自分で一番お気に入りのfontsizeをpoint単位で各パーツごとに決めておくのが最善だと思いますが,図の縮尺に応じてそれを変更させるが面倒くさい場合は,コード中で

plt.rcParams['font.size'] = 18

のようにデフォルトのfont.sizeだけ変更して,ほかは相対指定にすると結構便利だと思います.

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
7