WSL上のmatplotlibで日本語フォント付き可視光スペクトルバーを生成する方法

Python の matplotlib を使って「可視光スペクトルバー」を描画し、日本語タイトルを付けて画像として保存する方法を紹介します。
Linux や WSL など日本語フォント環境が不完全な場合でも、豆腐(□)にならずにちゃんと日本語が表示されるノウハウです。


この記事でわかること

  • Python で可視光スペクトルを描く方法
  • matplotlib に日本語フォントを正しく適用する方法
  • 日本語が「豆腐(□)」にならない方法

環境

  • OS:Ubuntu 20.04/22.04(WSL でも可)
  • Python:3.8+
  • matplotlib:3.x
  • 使用フォント:Noto Sans CJK JP

フォントの準備

まず、日本語フォントをインストールします。

sudo apt install fonts-noto-cjk

フォントが入ったか確認します:

fc-list :lang=ja | grep -i "noto"

出力例:

/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK JP:style=Regular

matplotlibでスペクトルバーを描く+日本語タイトル

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import font_manager as fm

# フォントファイルパスを明示的に指定
font_path = "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc"
jp_font = fm.FontProperties(fname=font_path)

def wavelength_to_rgb(wavelength):
gamma = 0.8
R = G = B = 0.0
if 380 <= wavelength <= 440:
R = -(wavelength - 440) / (440 - 380)
B = 1.0
elif 440 <= wavelength <= 490:
G = (wavelength - 440) / (490 - 440)
B = 1.0
elif 490 <= wavelength <= 510:
G = 1.0
B = -(wavelength - 510) / (510 - 490)
elif 510 <= wavelength <= 580:
R = (wavelength - 510) / (580 - 510)
G = 1.0
elif 580 <= wavelength <= 645:
R = 1.0
G = -(wavelength - 645) / (645 - 580)
elif 645 <= wavelength <= 780:
R = 1.0
factor = 1.0
if 380 <= wavelength <= 420:
factor = 0.3 + 0.7*(wavelength - 380)/(420 - 380)
elif 700 <= wavelength <= 780:
factor = 0.3 + 0.7*(780 - wavelength)/(780 - 700)
R = (R * factor)**gamma
G = (G * factor)**gamma
B = (B * factor)**gamma
return (R, G, B)

# 可視光スペクトルの RGB 値を生成
wavelengths = np.linspace(380, 780, 400)
rgb_values = [wavelength_to_rgb(wl) for wl in wavelengths]

# プロット
fig, ax = plt.subplots(figsize=(8, 1))
ax.imshow([rgb_values], extent=[380, 780, 0, 1], aspect='auto')
ax.set_xticks([400, 500, 600, 700])
ax.set_yticks([])
ax.set_title("可視光スペクトル(380〜780nm)", fontproperties=jp_font)

# 保存
plt.savefig("spectrum_bar.png", dpi=300, bbox_inches='tight')
print("画像を保存しました:spectrum_bar.png")

ポイントまとめ

問題解決策
日本語が豆腐になるFontProperties(fname=...) で直接フォントファイルを指定
rcParams['font.family'] が効かないOS依存があるため非推奨、個別指定が確実
.ttc が読めない?matplotlib は .ttc もサポート、ただし get_name() で確認推奨
spectrum_bar.png に日本語タイトル付きで保存fontproperties=jp_font を明示する

おわりに

この方法を使えば、科学データ可視化・教育資料・プレゼンに使える高品質な図を Python だけで自動生成できます。

matplotlib で日本語フォントを安全に使うには、rcParams ではなく FontProperties(fname=...) が正解です!


参考リンク

コメント

  1. voxjzdywmljjneexiksqngmlqqggir

  2. zlgnxrfwmlkofelnrxylnmfjqyhurl

  3. znnfmmqdhdyeqrdyrnvesjvfmfglqp