環境:
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()
このようになる。
解決策
上付き・下付き文字をちょうど良い位置に付けるには、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()
説明
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
のようにしている。
因みに、
$SO_4^{2{-}}$
$NH_4^{+}$
のように+や-を{}で括るのは、演算子の前後に自動で挿入されるスペースを排除するためである。