Open WebUI 日本語グラフの文字化け問題

ozy's labo.


はじめに

Open WebUI で matplotlib を使った日本語グラフを描画したところ,
盛大に文字化け(Glyph missing)が発生しました.

当初は Docker 側のフォント問題だと考え,
コンテナへ日本語フォントを追加するなどの対策を試みました.
しかし状況は改善せず,原因は別の場所にあることが判明しました.

本記事は,その探索過程と最終的な解決構成の記録です.


序盤の迷走(なぜ Docker 対策が無意味だったのか)

最初は以下を疑いました.

  • Docker イメージに日本語フォントが入っていない
  • matplotlibrc が読み込まれていない
  • コンテナ内の locale 設定の問題

しかし後から分かったことは,

そもそもコードは Docker 内で実行されていなかった

という事実です.

Open WebUI のデフォルト Python 実行は,
ブラウザ内の pyodide(WebAssembly版Python)でした.

つまり,

  • OSフォントは使えない
  • Linux にフォントを入れても無意味
  • コンテナに何を入れても影響しない

という構造だったのです.


ブラウザ内Pythonの正体

Open WebUI の「ブラウザ実行」は
pyodide という WebAssembly ベースの Python 環境です.

特徴:

  • 完全にブラウザ内で実行
  • OSフォント非依存
  • 仮想的なファイルシステム
  • 画像は base64 で描画

つまり「ローカルLinux上のPython」ではありません.


画像はキャッシュか?

途中で

「今表示されているグラフはキャッシュではないか?」

という疑念も生じました.

見極め方法:

  • グラフタイトルを毎回変更
  • print 文を入れる
  • 実行ログを確認

これにより,
表示画像は毎回再生成されていることを確認しました.

問題はキャッシュではありませんでした.


解決方針:外部 Jupyter を使う

pyodide をやめ,
外部 Jupyter を実行エンジンとして利用します.

これにより,

Open WebUI → Jupyter → OS上のPython

という構成になります.


Jupyter のインストール

あとから必要になったものもあって,最終的にインストールはこんな感じです.

pip install notebook jupyter
pandas matplotlib networkx


Jupyter 起動スクリプト

重要なのは matplotlib の設定ディレクトリです.

#!/bin/bash

export MPLCONFIGDIR=/home/XXX/.config/matplotlib

jupyter notebook \
  --ip=0.0.0.0 \
  --port=8888 \
  --no-browser \
  --NotebookApp.token='XXXX'

なぜ MPLCONFIGDIR が必要か?

matplotlib は実行ユーザーごとに
設定ディレクトリを参照します.

これを明示しないと,

  • 予期しないディレクトリが使われる
  • 設定が無視される
  • 別環境のキャッシュが影響する

といった混乱が起きます.


matplotlibrc の中身

~/.config/matplotlib/matplotlibrc

font.family: Noto Sans CJK JP
axes.unicode_minus: False

日本語フォントには Noto を使用します.

sudo apt install fonts-noto-cjk


Open WebUI 側の設定

Open WebUI には

  • エンジン
  • コードインタプリタ

の2つがあります.

これは

  1. LLM がコード生成
  2. 実行エンジンへ送信

という分離設計のためです.

設定内容:

  • Type: Jupyter
  • URL: http://<JUPYTER_IP>:8888
  • Token: XXXX

動作確認:

curl "http://localhost:8888/api/kernels?token=XXXX"

正常なら

[]

が返ります.


グラフ描画時の様々な問題 ModuleNotFoundError とか

例:

ModuleNotFoundError: No module named 'pandas'

これは Jupyter が使用している Python 環境に
パッケージが入っていないだけです.

確認:

import sys
print(sys.executable)

インストール:

/path/to/python -m pip install pandas

その他,色々問題が出ます.最終的に,以下の様な解決策を取りました.

pip uninstall -y numpy
pip install numpy --upgrade
pip install numpy==1.26.4
pip install -U matplotlib
pip install matplotlib>=3.8


結論

今回の文字化け問題の本質は,

  • フォント不足ではなく
  • Docker設定でもなく
  • matplotlibrcの誤記でもなく

実行環境の誤認

でした.

pyodide(ブラウザ内Python)ではなく,
外部Jupyterに切り替えることで完全解決しました.


所感

LLMはしばしば

「Windows前提でMeiryoを指定する」

といった環境誤認を行います.

外部実行構成では,

  • 実行環境を明示する
  • フォントを明示する
  • 実行パスを確認する

この3点が極めて重要です.

今回の構成で,
Open WebUI から日本語グラフを安定して描画できるようになりました.

追記:モデル側へのシステムプロンプト指定の重要性

今回の検証中に判明したもう一つの重要点は,
「モデルがどのOS環境を前提にコードを書くか」です.

LLMは特に指定しない場合,

  • Windows前提で Meiryo を指定する
  • Mac前提で Hiragino を指定する
  • Linux環境でも存在しないフォントを書いてしまう

といった挙動を取ることがあります.

そのため,Open WebUI のシステムプロンプトに
実行環境を明示する必要があります.

例:

この実行環境は Linux (Ubuntu系) です.
matplotlibの日本語フォントは Noto Sans CJK JP を使用してください.
Meiryo や Hiragino は存在しません.
グラフ描画時は plt.show() を必ず実行してください.

この指定を加えることで,

  • 不存在フォントの指定
  • OS依存コードの混入
  • 無意味なWindows向け設定

を防ぐことができます.

今回の問題はフォントそのものよりも,
「モデルの環境誤認」が最大の不安定要因でした.

外部実行エンジン構成では,
実行環境の明示はほぼ必須と言えます.


Date: 2026-03-07

Author: ozyukiwo

Created: 2026-03-11 水 08:08

Emacs 26.3 (Org mode 9.1.9)

Validate