Pynote

Python、機械学習、画像処理について

matplotlib - 日本語のテキストを使う方法について

日本語を使おうとすると文字化けする。

matplotlib で日本語のテキストを表示しようとしても表示できない。

import numpy as np
import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5, 6, 7]
y1 = [1, 1, 2, 3, 5, 8, 13]
y2 = [0, 2, 4, 6, 8, 10, 12]
y3 = [1, 3, 5, 7, 9, 11, 13]

y = np.vstack([y1, y2, y3])

labels = ["フィボナッチ数列", "偶数", "奇数"]

fig, ax = plt.subplots()
ax.stackplot(x, y1, y2, y3, labels=labels)
ax.legend(loc=2)
plt.show()

これは設定されているフォントが日本語に対応したフォントでないのが原因である。

print(plt.rcParams['font.family'])  # ['DejaVu Serif']

Ubuntu の場合

日本語フォントがあるかどうか確認する。

以下のスクリプトを実行し、日本語フォントがあるかどうか確認する。

import matplotlib.font_manager as fm

# フォント一覧
for font in fm.findSystemFonts():
    print(fm.FontProperties(fname=font).get_name())
Liberation Serif
DejaVu Sans
Liberation Mono
Liberation Mono
DejaVu Sans Mono
Liberation Sans Narrow
DejaVu Sans Mono
Liberation Sans
Liberation Sans Narrow
Liberation Serif
DejaVu Serif
DejaVu Sans
...

日本語フォントがなかった場合は、フォント (今回は Takao フォント) をインストールする。

$ apt-get install -y fonts-takao
$ fc-cache -f -v

matplotlib の設定ファイルを編集する。

matplotlib の設定は、~/.config/matplotlib/matplotlibrc から読み込まれる。こちらが存在しない場合は、<モジュールのパス>/mpl-data/matplotlibrc の設定が読み込まれる。

以下のスクリプトを実行し、~/.config/matplotlib/matplotlibrc を作成する。

import os
import shutil
import matplotlib as mpl

mpl_dirpath = os.path.dirname(mpl.__file__)
# デフォルトの設定ファイルのパス
default_config_path = os.path.join(mpl_dirpath, 'mpl-data', 'matplotlibrc')
# カスタム設定ファイルのパス
custom_config_path = os.path.join(mpl.get_configdir(), 'matplotlibrc')

os.makedirs(mpl.get_configdir(), exist_ok=True)
shutil.copyfile(default_config_path, custom_config_path)

実行して設定ファイルがコピーされたら、~/.config/matplotlib/matplotlibrc をエディタで開き、以下の行を追加する。

font.family : <フォント名>

font.family : TakaoPGothic

キャッシュを削除する。

matplotlib ではフォントの情報をキャッシュするようになっているので、キャッシュを再構築しないと反映しない。

import matplotlib as mpl
mpl.font_manager._rebuild()  # フォントのキャッシュを再構築する。

Windows

日本語フォントがあるかどうか確認する。

以下のスクリプトを実行し、日本語フォントがあるかどうか確認する。

import matplotlib.font_manager as fm

# フォント一覧
for font in fm.findSystemFonts():
    print(fm.FontProperties(fname=font).get_name())
Lucida Sans
Wide Latin
Nirmala UI
Colonna MT
Onyx
Copperplate Gothic Bold
MV Boli
Gill Sans MT
Lucida Fax
Agency FB
Segoe UI
Californian FB
...

matplotlib の設定ファイルを編集する。

matplotlib の設定は、C:/Users/<ユーザー名>/.matplotlib/matplotlibrc から読み込まれる。こちらが存在しない場合は、<モジュールのパス>/mpl-data/matplotlibrc の設定が読み込まれる。

以下のスクリプトを実行し、C:/Users/<ユーザー名>/.matplotlib/matplotlibrc を作成する。

import os
import shutil
import matplotlib as mpl

mpl_dirpath = os.path.dirname(mpl.__file__)
# デフォルトの設定ファイルのパス
default_config_path = os.path.join(mpl_dirpath, 'mpl-data', 'matplotlibrc')
# カスタム設定ファイルのパス
custom_config_path = os.path.join(mpl.get_configdir(), 'matplotlibrc')

os.makedirs(mpl.get_configdir(), exist_ok=True)
shutil.copyfile(default_config_path, custom_config_path)

実行して設定ファイルがコピーされたら、C:/Users/<ユーザー名>/.matplotlib/matplotlibrc をエディタで開き、以下の行を追加する。

font.family : <フォント名>

font.family : Noto Sans CJK JP

キャッシュを削除する。

matplotlib ではフォントの情報をキャッシュするようになっているので、キャッシュを再構築しないと反映しない。

import matplotlib as mpl
mpl.font_manager._rebuild()  # フォントのキャッシュを再構築する。

確認する。

正しく表示できることが確認できた。

import numpy as np
import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5, 6, 7]
y1 = [1, 1, 2, 3, 5, 8, 13]
y2 = [0, 2, 4, 6, 8, 10, 12]
y3 = [1, 3, 5, 7, 9, 11, 13]

y = np.vstack([y1, y2, y3])

labels = ["フィボナッチ数列", "偶数", "奇数"]

fig, ax = plt.subplots()
ax.stackplot(x, y1, y2, y3, labels=labels)
ax.legend(loc=2)
plt.show()


うまくいかない場合

  • 編集した設定ファイルが読みこまれていることを確認する。
import matplotlib as mplt
mpl.matplotlib_fname()  # '/root/.config/matplotlib/matplotlibrc'
  • 設定ファイルが読みこまれるのは import 時だけなので、IPython Notebook を使用している場合は一旦 Shutdown する。
  • フォントやキャッシュが削除されているかを確認する。
import matplotlib as mpl
mpl.font_manager._rebuild()  # フォントのキャッシュを再構築する。
  • フォント名が間違っていないか確認する。フォント名は空白を含む場合も、引用符で囲ったりしない。
✕ font.family : "Noto Sans CJK JP"
○ font.family : Noto Sans CJK JP