8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

データ可視化・視覚化Advent Calendar 2019

Day 2

matplotlibの日本語フォントについて(Macの場合)

Posted at

結論

こうすれば良いはず。
もっと良いものや、考慮漏れがあれば追記します。

# フォント設定
plt.rcParams['font.family'] = 'Hiragino Sans'
# 太さ設定
plt.rcParams['font.weight'] = 'bold'

"""
fig,ax = plt.subplots()
ax.plot()...
などのプロット
"""

# legend使うとき
#legend_properties = {'size':14,'weight':'bold'}
#ax.legend(prop=legend_properties)


# plt.draw()が無いとget_ticklabels()で帰ってくるtextが空文字になる
plt.draw()
# ticklabelのフォントはrc設定では変えられないっぽい
ax.set_xticklabels(ax.get_xticklabels(),fontsize=14,fontweight='bold')
ax.set_yticklabels(ax.get_yticklabels(),fontsize=14,fontweight='bold')

導入

import matplotlib.font_manager
[f.name for f in matplotlib.font_manager.fontManager.ttflist]

# >['DejaVu Serif Display',
# 'STIXGeneral',
# ...]

となりますが、よくよく見てみると、同じ文字列が複数存在していることがわかります。
例えばMacの場合

l = [f.name for f in matplotlib.font_manager.fontManager.ttflist]
l.count("Hiragino Sans")
#> 10

となります。何故10もあるのでしょうか。
それを知るために上のリスト内包表記でf.nameとしているころを、一旦fにして、fについて調べてみましょう。

l = [f for f in matplotlib.font_manager.fontManager.ttflist]
type(l[0])
# > matplotlib.font_manager.FontEntry

となるので、この各項目はmatplotlib.font_manager.FontEntryクラスのオブジェクトであることがわかります。
matplotlib.font_manager.FontEntryのクラス変数を見てましょう。

l_hiragino= [f for f in matplotlib.font_manager.fontManager.ttflist if f.name == 'Hiragino Sans']

として、Hiragino Sansのものだけを比較してみます。

matplotlib.font_manager.FontEntry.name

  • 詳しく書くまでもないので、これはl_hiraginoの全ての項目で"Hiragino Sans"になります。

matplotlib.font_manager.FontEntry.fname

[f.fname for f in l_hiragino]
"""
 >['/System/Library/Fonts/ヒラギノ角ゴシック W5.ttc',
 '/System/Library/Fonts/ヒラギノ角ゴシック W0.ttc',
 '/System/Library/Fonts/ヒラギノ角ゴシック W6.ttc',
 '/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc',
 '/System/Library/Fonts/ヒラギノ角ゴシック W9.ttc',
 '/System/Library/Fonts/ヒラギノ角ゴシック W2.ttc',
 '/System/Library/Fonts/ヒラギノ角ゴシック W8.ttc',
 '/System/Library/Fonts/ヒラギノ角ゴシック W1.ttc',
 '/System/Library/Fonts/ヒラギノ角ゴシック W4.ttc',
 '/System/Library/Fonts/ヒラギノ角ゴシック W7.ttc'] 
"""

これを見ると、各要素は全てヒラギノ角ゴシックで、太さの違うもの1になっていることがわかります。
ヒラギノ丸ゴシックについても見てみると

l_hiragino_maru= [f for f in matplotlib.font_manager.fontManager.ttflist if f.name == 'Hiragino Maru Gothic Pro']
[f.fname for f in l_hiragino_maru]
# > ['/System/Library/Fonts/ヒラギノ丸ゴ ProN W4.ttc']

となり太さが一種類のものしか用意されていないことがわかります。
これでどのような影響が出るのかを見てみましょう。
matplotlib.font_manager.FontEntryの他のクラス変数はそこまで大きな発見などないので、後ろの方に載せておきます。

ウェイト設定による違い

ウェイト設定出来るヒラギノ角ゴシック

まずヒラギノ角ゴシックで例を見てみましょう

# フォントをヒラギノ角ゴシックで
plt.rcParams['font.family'] = 'Hiragino Sans'  

fontsize=default, fontweight=default

fig,ax = plt.subplots(figsize=(3,3))
ax.annotate("テスト",xy=(0.5,0.5))

font_test1.png

うっす!!
ということでフォントのサイズを変えてみましょう

fontsize=18, fontweight=default

fig,ax = plt.subplots(figsize=(3,3))
ax.annotate("テスト",xy=(0.5,0.5),fontsize=18)

font_test2.png
まあ読めるようにはなりましたが、解像度が高くないような印象を受けます。
そこで太さを変更してみましょう。

fontsize=default, fontweight="bold"

fig,ax = plt.subplots(figsize=(3,3))
ax.annotate("テスト",xy=(0.5,0.5),weight="bold")

font_test3.png

フォントサイズを大きくしなくても読みやすい印象を受けます。
fontweightについてはここ2を参照すると

0-1000の数値で設定、もしくは' 'ultralight', 'light', 'normal', 'regular', 'book', 'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black'から選択

とあります。
この差を見てみましょう

fig,ax = plt.subplots(figsize=(3,3))
ax.annotate("テスト",xy=(0.1,0.1),weight="ultralight",fontsize=18)
ax.annotate("テスト",xy=(0.1,0.2),weight="light",fontsize=18)
ax.annotate("テスト",xy=(0.1,0.3),weight="normal",fontsize=18)
ax.annotate("テスト",xy=(0.1,0.4),weight="regular",fontsize=18)
ax.annotate("テスト",xy=(0.1,0.5),weight="book",fontsize=18)
ax.annotate("テスト",xy=(0.1,0.6),weight="medium",fontsize=18)
ax.annotate("テスト",xy=(0.1,0.7),weight="roman",fontsize=18)
ax.annotate("テスト",xy=(0.1,0.8),weight="semibold",fontsize=18)
ax.annotate("テスト",xy=(0.1,0.9),weight="demibold",fontsize=18)
ax.annotate("テスト",xy=(0.5,0.9),weight="demi",fontsize=18)
ax.annotate("テスト",xy=(0.5,0.8),weight="bold",fontsize=18)
ax.annotate("テスト",xy=(0.5,0.7),weight="heavy",fontsize=18)
ax.annotate("テスト",xy=(0.5,0.6),weight="extra bold",fontsize=18)
ax.annotate("テスト",xy=(0.5,0.5),weight="black",fontsize=18)

font_test4.png

2種類しか種類がないように見えます…
また、もう少し調べてみると

fontweightは細かく指定しても反映されない
引用元:http://ebcrpa.jamstec.go.jp/~yyousuke/matplotlib/options.html

との記述もあります。

それでは、これらを踏まえてデフォルトのrc設定を変更しましょう。3,4

# フォント設定
plt.rcParams['font.family'] = 'Hiragino Sans'
# 太さ設定
plt.rcParams['font.weight'] = 'bold'

"""
fig,ax = plt.subplots()
ax.plot()...
などのプロット
"""

# legend使うとき
#legend_properties = {'size':14,'weight':'bold'}
#ax.legend(prop=legend_properties)


# plt.draw()が無いとget_ticklabels()で帰ってくるtextが空文字になる
plt.draw()
# ticklabelのフォントはrc設定では変えられないっぽい
ax.set_xticklabels(ax.get_xticklabels(),fontsize=14,fontweight='bold')
ax.set_yticklabels(ax.get_yticklabels(),fontsize=14,fontweight='bold')

以下蛇足

matplotlib.font_manager.FontEntry.size

[f.size for f in l_hiragino]

"""
> ['scalable',
 'scalable',
 'scalable',
 'scalable',
 'scalable',
 'scalable',
 'scalable',
 'scalable',
 'scalable',
 'scalable']
"""

となり全て'scalable'となります。これについては公式doc5

If size2 (the size specified in the font file) is 'scalable'

という記述があることから、'saclable'であるとは、サイズがフォントファイルによって指定されるものである、ということがわかります。
私の環境でヒラギノ以外のフォントも見てみましたが、全てscalableとなったのであまり良くわかりませんが、太さが指定されるということなのでしょうか…

matplotlib.font_manager.FontEntry.stretch

[f.stretch for f in l_hiragino]
"""
> ['normal',
 'normal',
 'normal',
 'normal',
 'normal',
 'normal',
 'normal',
 'normal',
 'normal',
 'normal']
"""

ヒラギノでは全てnormalでしたが、condensedになっているものも確認できました。

公式doc5

The result is the absolute value of the difference between the CSS numeric values of stretch1 and stretch2

とあるので、CSSのfont-stretch6を参照するとフォントの幅を言っているのだと思います。

matplotlib.font_manager.FontEntry.style

[f.style for f in l_hiragino]
"""
> ['normal',
 'normal',
 'normal',
 'normal',
 'normal',
 'normal',
 'normal',
 'normal',
 'normal',
 'normal']
"""

これもヒラギノでは全てnormalになりましたが、なかにはitalicになっているものも確認できました。
これは斜体などの書体の情報でしょう。

  1. https://fontnavi.jp/zakkuri/206-font_weight.aspx

  2. https://qiita.com/eriho/items/21302ab7e95a2721b9f8

  3. https://stackoverflow.com/questions/32700935/get-xticklabels-contains-empty-text-instances

  4. https://stackoverflow.com/questions/35537895/matplotlib-legend-how-to-specify-font-weight

  5. https://matplotlib.org/3.1.1/api/font_manager_api.html 2

  6. https://dekiru.net/article/13115/

8
7
0

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
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?