Lambdaカクテル

集団への盲従を激しく嫌う

Google Colaboratory+Seabornでグラフに日本語を表示する

Google Colaboratoryでmatplotlib(seaborn)を使ったグラフ描画を行う場合,そのままでは日本語が豆腐になってしまう. インターネットを探したところ,情報が散逸していたため,備忘録も兼ねてメモを残す.

TL;DR

  • 日本語フォント,ここではIPAゴシックをインストールする
    • !apt-get -y install fonts-ipafont-gothic
  • matplotlibが保持しているフォントキャッシュを飛ばす
    • !rm /content/.cache/matplotlib/fontList.jsonを実行し,ランタイムを再起動する
      • /root/.cache/matplotlib/fontList.json になっているらしい. (後述)
  • 描画時にフォントを指定する
    • sns.set(font='IPAGothic')する
    • plt.rcなどと併用してはいけない

フォントのインストール

Google Colaboratory(Colab)でmatplotlibが日本語の描画をうまく行えないのは,単に日本語を表示できるフォントが入っていないからである.

したがって,日本語が表示できるフォントをインストールし,これを利用するべくmatplotlibに指示すれば,グラフに日本語を表示することができる.

Colabには,Jupyter Notebook同様に,!を使ってシェルコマンドを実行できるので,これを用いてフォントをインストールする.

!apt-get -y install fonts-ipafont-gothic

この操作はディスクが初期化されると,つまりランタイム(より正確には,ランタイムが実行されているマシン)が停止するたびに再度実行する必要がある. この操作は羃等なので,臨床的には,ノートブックの先頭に「おまじない」として記述して毎回実行するようにすればよいだろう.

matplotlibが保持しているフォントキャッシュを飛ばす

Seabornはmatplotlibのラッパーであり,フォントといったコアな設定はmatplotlibが担当している.

matplotlibは,(おそらくフォント読み込みを高速化するために)利用可能なフォントのリストをファイルに保存する. 新規にフォントをインストールしても,先にmatplotlibがimportされている場合は,matplotlibはフォントの追加に気付くことができないので,フォントを認識させるためにはキャッシュファイルを削除してキャッシュクリアを行う必要がある.

キャッシュがどこに保存されるかはmatplotlibの設定によるが,Colabでは /content/.cache/matplotlib/fontList.jsonに保存されている.

追記: 最近は/root/.cache/matplotlib/fontList.json に保存されているようなので,こちらも確認してほしい.

peperonperopero.hatenadiary.com

ちなみにキャッシュ全般の保存先は,get_cachedir()メソッドで得られる.これで得られたディレクトリの中にfontList.jsonが保存されている.

import matplotlib
print(matplotlib.get_cachedir())

キャッシュファイルを削除するには,シェルコマンドを使う.

!rm /content/.cache/matplotlib/fontList.json

この操作もフォントのインストール同様に,ランタイムが停止すると元に戻ってしまうので,初回のマシン起動時などに適宜実行する必要がある. また,キャッシュファイルを削除してもmatplotlib自体はキャッシュファイルから読み取ったキャッシュをメモリに保持しているので,いったんランタイムを再起動してメモリをクリアする必要がある.

したがって,順序としては

  1. フォントをインストールする
  2. キャッシュファイルを削除する
  3. ランタイムを再起動する
  4. matplotlibなどをimportする
  5. 続きの処理を実行していく

という流れをとる.

描画時にフォントを指定する

基本的にseabornで日本語を描画する場合,matplotlibを直接操作する必要はない.というのも,matplotlibの設定インターフェイスもseabornがラップしているからだ.

筆者はここで一度ハマっているのでちょっとだけ注意が必要だとおもう.

Seabornを使ったグラフを日本語化するには以下のようにする.

# import seaborn as sns

sns.set(font='IPAGothic')

# 必要によっては文字を大きくする
# sns.set(font='IPAGothic', font_scale=1.2)

# matplotlibにrcを渡したいときは以下のようにする
# sns.set(font='IPAGothic', rc={"axes.facecolor": "grey"})

フォントを指定するだけなら簡単だが,最後の項目,matplotlibにrcを渡す場合に注意が必要だ.seabornはmatplotlibのラッパーなので,sns.setは内部でmatplotlib.rcなどを書き換えているようだ(未確認). このため,matplotlibへの設定とsns.setが平行して行われると,一方がもう一方の変更を上書きして無効化してしまう.

やってはいけない使い方を以下に挙げた.

# import matplotlib.pyplot as plt

sns.set(font='IPAGothic')
plt.style.use('grayscale') # こういう使い方をしてはいけない! ここで↑の設定がかき消される.
sns.set(font='IPAGothic')
sns.set_style('whitegrid') # set_styleを後に使うとフォントを上書きしてしまうので前に使わなければならない!
plt.rcParams['font.family'] = 'IPAPGothic'
sns.set() # ここでフォントの設定が消えてしまう!