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']

インストールされているフォント一覧を確認する。

以下のコードでインストールされているフォント一覧を確認できる。

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

Ubuntu の場合

日本語対応のフォントをインストールする。

日本語フォントがなかった場合は、フォント (今回は 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

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 時だけなので、Jupyter Notebook を使用している場合は一旦 Shutdown して、ノートブックを開き直す。
  • フォントやキャッシュが削除されているかを確認する。
import matplotlib as mpl
mpl.font_manager._rebuild()  # フォントのキャッシュを再構築する。
  • フォント名が間違っていないか確認する。フォント名は空白を含む場合も、引用符で囲ったりしない。
✕ font.family : "Noto Sans CJK JP"
○ font.family : Noto Sans CJK JP