手元の環境で日本語を表示可能なフォントのみを列挙したいとき向けです。fonttools が必要です (pip で入ります)。以下で列挙できます。参考文献 [1] を参考にしました。
import matplotlib
import fontTools
def is_character_supported(char, font_path):
font = fontTools.ttLib.TTFont(font_path, fontNumber=0)
cmap = font.getBestCmap()
if cmap and ord(char) in cmap:
return True
return False
def get_font_names(char):
font_names = set()
for font_path in matplotlib.font_manager.findSystemFonts():
if is_character_supported(char, font_path):
font_name = matplotlib.font_manager.FontProperties(fname=font_path).get_name()
font_names.add(font_name)
return sorted(list(font_names))
font_names = get_font_names('凪') # 適当な1文字
print(len(font_names))
print(font_names)
31
['BIZ UDGothic', 'BIZ UDMincho', 'HGGothicE', 'HGGothicM',
'HGGyoshotai', 'HGKyokashotai', 'HGMaruGothicMPRO', 'HGMinchoB',
'HGMinchoE', 'HGSeikaishotaiPRO', 'HGSoeiKakugothicUB', 'HGSoeiKakupoptai',
'HGSoeiPresenceEB', 'M PLUS 1', 'M PLUS 1 Code', 'M PLUS 2',
'MS Gothic', 'MS Mincho', 'Meiryo', 'Microsoft JhengHei',
'Microsoft YaHei', 'Ricty Diminished', 'Ricty Diminished Discord', 'Rounded Mplus 1c',
'Rounded Mplus 1c Bold', 'SimSun', 'UD Digi Kyokasho N-B', 'UD Digi Kyokasho N-R',
'Ume Gothic', 'Yu Gothic', 'Yu Mincho']
補足
- 日本語を表示可能なフォントをみつけるのに、可能なフォントをすべて描画してみて「豆腐」(□) にならないか確認する方法もありますが、それだと使用可能なフォント名のみを列挙しづらいので、列挙したいとき向けです。
- 豆腐があるとグラフ描画時に UserWarning が出ますが、これでもって検知しようとするとノートブックにグラフ or エラーメッセージがぶわっと出てしまうことが避けられないと思います (たぶん)。
- 上記のスクリプトは
getBestCmap()
でそのフォントの Unicode コードポイント‐グリフID の対応表を取得し、「凪」という文字の Unicode コードポイントが対応表に含まれているかをみています [1][2]。「凪」を選んだのは国字なので中国語向けフォントが排除されるかと思ったのですが、別に排除されなかったです。
そういうわけで、私のお気に入りのフォント名が Rounded Mplus 1c であったのがわかったので指定しますが、このフォントを持っていないチームメンバーにも配慮して以下のようにした方がよさそうです [3]。
%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['Rounded Mplus 1c', 'Meiryo']
フォント名を列挙するだけなく描画してみて選びたいのだという場合は、例えば以下のようにするとみられると思います (お手元のフォント数が多かったら figsize を調整してください)。
%matplotlib inline
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(7, 7))
for i, font_name in enumerate(font_names):
plt.rcParams['font.family'] = font_name
ax.text(0, i, font_name + ' 0123456789 来ぬ人を松帆の浦の夕凪に', size=11)
ax.set_ylim([0, len(font_names)])
plt.show()