LoginSignup
14
16

More than 1 year has passed since last update.

matplotlibで上付き文字が上過ぎ、下付き文字が下過ぎる問題の解決

Last updated at Posted at 2019-08-05

環境:
Ubuntu 18.04.5 LTS (Windows Subsystem for Linux)
Python 3.6.9
Matplotlib 2.1.1

※matplotlibのバージョン3.4.2以降で、mathtextのクラスが_mathtextサブモジュールに移動していました。とのコメントをいただき、本文に追記しました。
ご指摘いただきありがとうございました。

問題点

matplotlibのmathtextはもともと数式用のためか、フォントによっては上付き文字が上過ぎ下付き文字が下過ぎる。

例えば、以下のようにTimes New Romanを使った場合、


import matplotlib.pyplot as plt

plt.rcParams.update({'mathtext.default': 'default',
                     'mathtext.fontset': 'stix',
                     'font.family': 'Times New Roman',
                     'font.size': 12,
                     'figure.figsize': (3, 3)})

plt.text(0.5, 0.9, '$NH_4^{+}$',    ha='center', va='center')
plt.text(0.5, 0.7, '$SO_4^{2{-}}$', ha='center', va='center')
plt.text(0.5, 0.5, '$H_2O$',        ha='center', va='center')
plt.text(0.5, 0.3, '$(cm^{{-}1})$', ha='center', va='center')
plt.text(0.5, 0.1, '$(s^{{-}1})$',  ha='center', va='center')
plt.savefig('default.png')
plt.show()

このような図(default.png)が生成される。
default.png

以下の解決策を施せば、生成される図は、
cmfc.png

このようになる。

解決策

上付き・下付き文字をちょうど良い位置に付けるには、Matplotlibのバージョンに応じ、以下のいずれかの2行を加えて、

# Matplotlib 3.4.2より前の場合
from matplotlib import mathtext
mathtext.FontConstantsBase = mathtext.ComputerModernFontConstants
# Matplotlib 3.4.2以降の場合
from matplotlib import _mathtext as mathtext
mathtext.FontConstantsBase = mathtext.ComputerModernFontConstants

FontConstantsBaseの中身をComputerModernFontConstantsの設定値に変更する。
すなわち、例えば、


import matplotlib.pyplot as plt
from matplotlib import mathtext

mathtext.FontConstantsBase = mathtext.ComputerModernFontConstants

plt.rcParams.update({'mathtext.default': 'default',
                     'mathtext.fontset': 'stix',
                     'font.family': 'Times New Roman',
                     'font.size': 12,
                     'figure.figsize': (3, 3)})

plt.text(0.5, 0.9, '$NH_4^{+}$',    ha='center', va='center')
plt.text(0.5, 0.7, '$SO_4^{2{-}}$', ha='center', va='center')
plt.text(0.5, 0.5, '$H_2O$',        ha='center', va='center')
plt.text(0.5, 0.3, '$(cm^{{-}1})$', ha='center', va='center')
plt.text(0.5, 0.1, '$(s^{{-}1})$',  ha='center', va='center')
plt.savefig('cmfc.png')
plt.show()

これを実行して、生成された図(cmfc.png)は先程の
cmfc.png

説明

mathtext.FontConstantsBaseで設定されている下付き・上付き文字(sub/superscripts)の仕様とそれらの初期値は、


    # Percentage of x-height of additional horiz. space after sub/superscripts
    script_space = 0.05

    # Percentage of x-height that sub/superscripts drop below the baseline
    subdrop = 0.4

    # Percentage of x-height that superscripts are raised from the baseline
    sup1 = 0.7

    # Percentage of x-height that subscripts drop below the baseline
    sub1 = 0.3

    # Percentage of x-height that subscripts drop below the baseline when a
    # superscript is present
    sub2 = 0.5

    # Percentage of x-height that sub/supercripts are offset relative to the
    # nucleus edge for non-slanted nuclei
    delta = 0.025

    # Additional percentage of last character height above 2/3 of the
    # x-height that supercripts are offset relative to the subscript
    # for slanted nuclei
    delta_slanted = 0.2

    # Percentage of x-height that supercripts and subscripts are offset for
    # integrals
    delta_integral = 0.1

ここで、x-heightは大文字"X"の高さ、baselineは"j"や"g"などの下端の位置に対応するようである。

一方、mathtext.ComputerModernFontConstantsの設定値は、


    script_space = 0.075
    subdrop = 0.2
    sup1 = 0.45
    sub1 = 0.2
    sub2 = 0.3
    delta = 0.075
    delta_slanted = 0.3
    delta_integral = 0.3

各項目を個々に設定したければ、mathtextをインポートした後、


mathtext.FontConstantsBase.delta = 0.01

のようにする。

#追伸

私はいつも、


from matplotlib import mathtext
mathtext.FontConstantsBase = mathtext.ComputerModernFontConstants
mathtext.FontConstantsBase.script_space = 0.01
mathtext.FontConstantsBase.delta = 0.01

として、
test.png

のようにしている。

因みに、


$SO_4^{2{-}}$
$NH_4^{+}$

のように+や-を{}で括るのは、演算子の前後に自動で挿入されるスペースを排除するためである。

14
16
1

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
14
16