Python
matplotlib

【matplotlib日本語表示】matplotlibrcを書き換えずに日本語表示する

matplotlibrcを書き換える権限がないのでフォント変更ができないのだけど、

世の中にごまんとあるmatplotlib日本語表示解決方法が書かれたブログを見てみると、大筋の流れとしては

  1. 日本語対応フォントをDLしてくる
  2. DLしたフォントを /fonts 以下にcpする
  3. matplotlibrcファイルのフォント指定を書き換える
  4. plotする

という手段で解決する。
ただし、自分の環境で困ったのは、ファイル書き込みの権限があまり無い状態では

  • 2 ← /fontディレクトリには勝手にファイルをコピーできない
  • 3 ← 権限がないのでファイルの書き換えができない

という問題がある。そんな環境でもmatplotlibで正しく日本語表示する方法です。

先に解決のための流れを書いておくと

  1. 日本語対応フォントを適当な場所にDLしてくる
  2. FontPropertiesにDLしたフォントの任意のパスを教える
  3. plotするときに fontproperties=font_prop を渡してあげる
  4. plotする→ok

です。

ちなみに、想定環境は ubuntu(※root権限なし)です。

日本語対応フォントをDLしてくる

ここは通常通り。
何も考えず TakaoPGothic当たりでもDLしましょう。以下から落とせます。
https://github.com/byrongibson/fonts/blob/master/backup/truetype.original/takao-gothic/TakaoPGothic.ttf

ちなみに、すでにTakaoをDL済みかどうかを確認したい場合は以下コマンドを実行

$ fc-list | grep Takao

matplotlibで日本語表示するためにTakaoPGothicのような日本語対応フォントが必要なわけですが、日本語対応フォントであれば必ずしもTakaoPGothicである必要は無いわけです。
現在すでにインストールされているフォントから日本語フォントを探すには、こちらの記事の「有効なフォントの一覧表示」を試してみてください。「IPA~~~」が日本語フォントです。
ただ、TakaoPGothicをDLする手間の方が少ないと思うので、既存フォントの確認せずにDLしちゃったら良いと思います。

FontPropertiesにDLしたフォントのパスを教える

特にめんどくさいこともなく、以下の4行を実行するだけ

import matplotlib
from matplotlib.font_manager import FontProperties

font_path = './TakaoPGothic.ttf'  #DLしたパスを指定. /font以下でなくても良い
font_prop = FontProperties(fname=font_path)

ポイントは、DLしたフォントデータ(TakaoPGothic.ttf)を、Linux的に正しいフォント格納場所(/usr/share/fonts/) に置かなくても、自分の好きな任意の場所にとりあえず置いておいて、そのパスをFontPropertiesの引数として渡してあげるだけ。

他のブログでは、DLしたフォントを/usr/share/fonts/に置けとけ的なことが書かれているが、ここにファイルをコピーする権限がない場合は上記のようにテキトーな場所に置いてしまってok

plotするときにfontproperties=font_propを渡してあげる

あとは、実際にplotするときにmatplotlibのplot関数にfontproperties=font_propを引数として渡してあげるだけ

# 例
plt.text(X[i, 0], X[i, 1], hoge, fontproperties=font_prop)

これで文字化け(豆腐)が出現すること無く日本語が出るはず

他のブログでは、matplotlibの環境ファイルであるmatplotlibrcファイルのfont.familyの箇所を、DLしたフォント名で指定して、使用するフォントを書き換えているがmatplotrcファイルを書き換えることができない弱い権限のときは plotする時にいちいち引数にfontproperties=font_propを渡してあげることで解決している
(※いちいち引数に書くのはややめんどくさくはあるが、そこまで頻繁にmatplotlibで日本語表示をしない人は、環境ファイルを書き換えて何かよくわからんことになってしまうより、暫定的に変更する方がむしろ楽かもしれない)

fontproperties=font_propをいちいち渡して日本語表示する際の注意点としては、
plt.legendするときだけfontproperties=font_propではなく、prop=font_propとなる点。

# 例
plt.legend(['hoge'], prop=font_prop, loc='upper left')

(備考)MatplotlibのFontキャッシュ削除

Fontのキャッシュが残っていると、設定変更しても反映されない可能性があるのでこれを削除する

$ rm ~/.cache/matplotlib/fontList.cache

ファイル名が異なる場合もあるので、~/.cache/matplotlib/以下でfontListがついてるファイルを見つけて削除する

参考

https://qiita.com/canard0328/items/a859bffc9c9e11368f37
https://qiita.com/gymnstcs/items/50432a12fb9139b316bc