matplotlibで日本語が豆腐「□」に文字化けし、正しく表示されないことがあります。その修正方法です。
豆腐とは
labelやtitle, legendに日本語(2バイト文字)を使うと、次のようなエラーが出て、日本語が正しく描画されません。
import matplotlib.pyplot as plt
# データ作成例
x = [1, 2, 3, 4]
y1 = [10, 8, 6, 4]
y2 = [2, 4, 6, 8]
# 線グラフ(マーカー付き)
plt.plot(x, y1, marker='o', label='Data 1')
plt.plot(x, y2, marker='x', label='Data 2')
# 凡例を表示
plt.legend()
plt.xlabel('X軸')
plt.ylabel('Y軸')
plt.title('凡例のマーカーサイズとフォントサイズ')
plt.show()
/Users/tmp/venv-metal-3.12/lib/python3.12/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 12531 (\N{KATAKANA LETTER N}) missing from font(s) DejaVu Sans.
fig.canvas.print_figure(bytes_io, **kw)

matplotlib で日本語を正しく表示するためには、日本語対応フォントをインストールし、matplotlib にそのフォントを指定する必要があります。
使用できる日本語フォントファミリの検索
まず、システムに日本語を表示できるフォント(例:Windowsなら「Meiryo」、LinuxやMacなら「IPAexGothic」など)がインストールされていることを確認します。
使用できるフォント名はシステム環境によって異なります。自分の環境で使用可能なフォント名を確認するためには、以下のコードを実行して利用可能なフォント一覧を調べることができます。
fontToolsがインストールされていない場合は、pip install fonttools
でインストールしてください。
import logging
logging.getLogger("fontTools").setLevel(logging.ERROR)
import matplotlib.font_manager as fm
from fontTools.ttLib import TTFont, TTCollection
def get_japanese_supported_families(font_path, test_char='あ'):
"""
指定したフォントファイル内で、テスト文字に対応しているフォントの
ファミリ名のリストを返す(TTCollectionにも対応)。
"""
families = []
try:
# TTC/OTCの場合はコレクションとして読み込み、それ以外はTTFontで読み込み
if font_path.lower().endswith(('.ttc', '.otc')):
collection = TTCollection(font_path)
fonts = collection.fonts
else:
fonts = [TTFont(font_path)]
for font in fonts:
# cmapテーブルをチェックし、テスト文字が含まれているか確認
has_japanese = False
for table in font['cmap'].tables:
if table.isUnicode() and ord(test_char) in table.cmap:
has_japanese = True
break
if not has_japanese:
continue
# nameテーブルからファミリ名(nameID=1)を取得
family_name = None
for record in font['name'].names:
if record.nameID == 1:
try:
family_name = record.string.decode(record.getEncoding())
except Exception:
family_name = record.string.decode('utf-8', errors='replace')
break
if family_name:
families.append(family_name)
else:
families.append("不明")
except Exception:
return []
return families
# システムにあるフォントのパス一覧を取得
system_fonts = fm.findSystemFonts()
# 各フォントファイルについて、日本語対応かつファミリ名が取得できるものを抽出
font_info = []
for font in system_fonts:
families = get_japanese_supported_families(font)
if families:
font_info.append((font, families))
print("日本語対応フォント:")
for path, families in font_info:
print(f"{', '.join(families)} : {path}")
コードを実行すると次のようなフォントのリストが表示されます。
Hiragino Sans, .Hiragino Kaku Gothic Interface : /System/Library/Fonts/ヒラギノ角ゴシック W1.ttc
Osaka : /System/Library/AssetsV2/com_apple_MobileAsset_Font7/0818d874bf1d0e24a1fe62e79f407717792c5ee1.asset/AssetData/OsakaMono.ttf
使用したいフォントファミリ名「Hiragino Sans」や「Osaka」あるいは、ファイルパスを覚えておきます。
フォントのリストが何も表示されない場合は、日本語フォントをどこかからダウンロードしておき、保存したパスを覚えておきます。
matplotlib にフォントを指定する
フォントファミリ名か、フォントファイルのパスの二通りの方法で指定できます。
(A)フォントファミリを指定する場合
import matplotlib.pyplot as plt
# フォントファミリを Osakaに指定
plt.rcParams['font.family'] = 'Osaka'
# マイナス記号などが文字化けしないようにする
plt.rcParams['axes.unicode_minus'] = False
plt.plot([1, 2, 3], [4, 5, 6])
plt.xlabel('日本語ラベル')
plt.title('日本語タイトル')
plt.show()

次のエラーが表示された場合は、一つ上の項目に従い、他のフォントファミリーを探して指定します。
findfont: Font family 'IPAexGothic' not found.
(B)フォントファイルパスを指定する場合
フォントファイルパスを指定するには次のようにします。
こちらの方法では、フォントをシステムにインストールしていなくても、フォントファイルを直接読み込んで使用することができます。
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
font_path = '/path/to/IPAexGothic.ttf' # 実際のフォントファイルのパスを指定
fontprop = fm.FontProperties(fname=font_path)
plt.title('日本語タイトル', fontproperties=fontprop)
plt.xlabel('ラベル', fontproperties=fontprop)
plt.plot([1, 2, 3], [4, 5, 6])
plt.show()
それでも表示されない場合
- フォントのパスやファイル名が誤っていないか確認する
- コードを実行している環境(Jupyter Notebook など)で再起動が必要な場合がある
- matplotlib のキャッシュが古い場合は、キャッシュを削除する(
matplotlib.font_manager._rebuild()
など)
上記の手順で正しいフォントを指定すれば、日本語が「□(豆腐)」ではなく正しく表示されるはずです。