問題概要
UbuntuシステムにJupyterHub環境を構築した。Matplotlibでグラフを描画できるが、UTF-8文字コードの日本語が表示されず、文字化けしてしまう。
背景情報
Ubuntuシステム環境
AMD64マシンで以下のUbuntuおよびPythonを実行。
- Distributor ID: Ubuntu
Description: Ubuntu 22.04.4 LTS
Release: 22.04
Codename: jammy - Python 3.10.12
- python3-venv/jammy-updates,jammy-security,now 3.10.6-1~22.04 amd64
JupyterHub環境
venv環境で以下のJupyterHubを実行。systemdで起動させる。
- jupyter_client==8.5.0
- jupyter_core==5.5.0
- jupyter_server==2.9.1
- jupyter_server_terminals==0.4.4
- jupyterhub==4.0.2
- jupyterlab==4.1.8
- jupyterlab-widgets==3.0.9
- jupyterlab_server==2.27.1
- matplotlib==3.8.1
- matplotlib-inline==0.1.6
解決策の概要
japanize_matplotlibではseabornなどmatplotlibを利用するモジュールのimportの前後関係に依存してprimary fontが変更され日本語が乱れることがあるとの情報があった。
import japanize_matplotlib
import seaborn
また、fontManagerへのフォント登録でも同様な懸念がある。
font_path = '/xxx/venv/lib/python3.10/site-packages/matplotlib/mpl-data/fonts/ttf/ipaexg.ttf'
font_prop = fm.FontProperties(fname=font_path)
font_name = font_prop.get_name()
fm.fontManager.addfont(font_path)
font_family = plt.rcParams['font.family']
plt.rcParams['font.' + font_family[0]].insert(0, font_name)
そこで、Matplotlibでfont設定するmatplotlibrcを修正することで対応し、ユーザープログラムの変更を不要とした。
手順
- JupyterHubを停止する。
$ sudo systemctl stop jupyterhub.service
サービス名は各ユーザーシステムに合わせてください。
2. matplotlibrcのオリジナルを保管。
$ sudo cp /xxx/venv/lib/python3.10/site-packages/matplotlib/mpl-data/matplotlibrc /xxx/venv/lib/python3.10/site-packages/matplotlib/mpl-data/matplotlibrc.original
3. matplotlibrcを修正。
262c262
< #font.family: sans-serif
---
> font.family: sans-serif
270c270
< #font.sans-serif: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
---
> font.sans-serif: Noto Sans CJK JP, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
デフォルト設定のfont.familyであるsans-serifをそのままに、font.sans-serifの先頭に日本語フォントを設定する。Noto Sans CJK JPはipaexg.ttfのように追加せずとも元々インストールされている。
修正するfont.sans-serifの行は、#でコメントしていても、記述が2つあると設定エラーとなるため、書き換える場合は#行でコピーを残さない。
4. JupyterHubを再起動。
$ sudo systemctl restart Jupyterhub.service
サービス名は各ユーザーシステムに合わせてください。
結果
各ユーザーが特別なモジュールのimportやfont設定せずとも日本語表示ができました。
注意事項
取り敢えず日本語表示できれば、という目的には合致しています。seabornのimportとの背反などの詳細な検証はできていませんが、仕組みから言ってあまり問題なさそうと考えています。