Python Matplotlib Chinese Font

👤 earl-chen 📦 v1.0.0 ⭐ 0.0 ⬇️ 854 下載
💻 開發程式設計 免費

📖 技能介紹

python-matplotlib-chinese-font

Python matplotlib 中文字型配置解決方案


📌 問題描述

matplotlib 預設不支援中文,中文會顯示為方塊/方框

控制台警告:

UserWarning: Glyph XXXXX missing from current font

根本原因:matplotlib 的預設字型不包含中文字元。


🎯 使用場景

當以下情況時使用此 Skill: 1. ✅ matplotlib 綁圖中中文顯示為方框/亂碼 2. ✅ 需要配置中文字型 3. ✅ 負號顯示為方框 4. ✅ 圖例、標題、座標軸標籤中文顯示異常 5. ✅ 跨平臺字型相容問題 6. ✅ 字型路徑配置問題 7. ✅ 字型快取問題


🚀 快速開始

第 0 步:下載字型檔案

# 建立字型目錄
mkdir -p fonts

# 下載 BabelStoneHan 字型(約 50MB)
curl -L -o fonts/BabelStoneHan.ttf "https://www.babelstone.co.uk/Fonts/Download/BabelStoneHan.ttf"

# 或者使用 wget
wget -O fonts/BabelStoneHan.ttf "https://www.babelstone.co.uk/Fonts/Download/BabelStoneHan.ttf"

其他字型選擇(小於 10MB): - WenQuanYi Micro Hei (文泉驛微米黑) - 約 4MB - SimHei (黑體) - 系統自帶 - Microsoft YaHei (微軟雅黑) - Windows 系統自帶

方法 1:複製模板(推薦)

# 複製配置模板到你的專案
cp ~/.openclaw/skills/python-matplotlib-chinese-font/templates/setup_font.py ./

方法 2:直接使用字型檔案

import os
import matplotlib.pyplot as plt
from matplotlib import font_manager as fm

# 字型檔案路徑(請修改為你的實際路徑)
font_file = './fonts/BabelStoneHan.ttf'

# 關鍵:顯式新增字型
fm.fontManager.addfont(font_file)

# 建立 FontProperties
font_prop = fm.FontProperties(fname=font_file)

# 設定全域性字型
plt.rcParams['font.family'] = font_prop.get_name()
plt.rcParams['axes.unicode_minus'] = False

# 使用
fig, ax = plt.subplots()
ax.set_title('中文標題', fontproperties=font_prop)
ax.set_xlabel('橫軸', fontproperties=font_prop)
ax.legend(['圖例'], prop=font_prop)

📋 完整配置程式碼(3 步)

第 1 步:下載並準備字型檔案

# 建立字型目錄
mkdir -p fonts

# 下載 BabelStoneHan 字型
curl -L -o fonts/BabelStoneHan.ttf "https://www.babelstone.co.uk/Fonts/Download/BabelStoneHan.ttf"

專案結構

your_project/
├── fonts/
│   └── BabelStoneHan.ttf  ← 中文字型檔案(需自行下載)
├── scripts/
│   └── your_script.py
└── ...

字型推薦: - BabelStoneHan.ttf(開源,支援中文)← 需自行下載,約 50MB - SimHei.ttf(黑體)- 系統自帶 - Microsoft YaHei.ttf(微軟雅黑)- Windows 系統自帶 - WenQuanYi Micro Hei(文泉驛微米黑)- 約 4MB


第 2 步:配置字型

import os
import matplotlib.pyplot as plt
from matplotlib import font_manager as fm

# 字型檔案相對於指令碼的路徑
_FONT_FILE_RELATIVE = os.path.join('..', '..', 'fonts', 'BabelStoneHan.ttf')

def _get_font_path():
    """獲取字型檔案的絕對路徑"""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    font_file = os.path.join(script_dir, _FONT_FILE_RELATIVE)
    return os.path.normpath(font_file)

def setup_chinese_font():
    """配置中文字型(相容所有 matplotlib 版本)"""
    font_file = _get_font_path()

    if os.path.exists(font_file):
        # 建立 FontProperties
        font_prop = fm.FontProperties(fname=font_file)
        font_name = font_prop.get_name()

        # 註冊字型(相容新舊版本 matplotlib)
        try:
            # 方法1:matplotlib 3.2+ 使用 addfont
            if hasattr(fm.fontManager, 'addfont'):
                fm.fontManager.addfont(font_file)
            else:
                # 方法2:舊版本 matplotlib,手動新增到字型列表
                try:
                    fm.fontManager.ttflist.append(fm.FontEntry(
                        fname=font_file,
                        name=font_name,
                        style=font_prop.get_style(),
                        variant=font_prop.get_variant(),
                        weight=font_prop.get_weight(),
                        stretch=font_prop.get_stretch(),
                        size=font_prop.get_size()
                    ))
                except Exception:
                    pass
        except Exception:
            pass

        # 設定全域性字型
        plt.rcParams['font.family'] = font_name
        plt.rcParams['axes.unicode_minus'] = False  # 解決負號顯示問題

        return font_prop

    return fm.FontProperties()

⚠️ 版本相容性說明

matplotlib 版本 方法 說明
≥ 3.2 fontManager.addfont() 推薦方法
< 3.2 fontManager.ttflist.append() 相容方法
    # 建立 FontProperties
    font_prop = fm.FontProperties(fname=font_file)

    # 設定全域性字型
    plt.rcParams['font.family'] = font_prop.get_name()
    plt.rcParams['axes.unicode_minus'] = False  # 解決負號顯示問題

    print(f"✅ 已載入中文字型: {font_file}")
    return font_prop
else:
    print(f"⚠️ 未找到字型檔案: {font_file}")
    return fm.FontProperties()

使用

chinese_font = setup_chinese_font()


---

### **第 3 步:在綁圖時使用字型**

#### **方法 A:全域性設定(推薦)**

```python
# 配置字型
chinese_font = setup_chinese_font()

# 綁圖時自動使用全域性字型
fig, ax = plt.subplots()
ax.set_title('中文標題')  # 自動使用全域性字型
ax.set_xlabel('橫軸標籤')
ax.legend(['圖例1', '圖例2'])

方法 B:區域性指定(精確控制)

# 配置字型
chinese_font = setup_chinese_font()

# 綁圖時顯式指定 fontproperties
fig, ax = plt.subplots()
ax.set_title('中文標題', fontproperties=chinese_font)
ax.set_xlabel('橫軸標籤', fontproperties=chinese_font)
ax.legend(['圖例1', '圖例2'], prop=chinese_font)

🎯 核心要點(5 個關鍵點)

1. 字型檔案路徑

# ❌ 錯誤:使用執行目錄
font_file = os.path.join(os.getcwd(), 'fonts', 'BabelStoneHan.ttf')

# ✅ 正確:使用指令碼所在目錄
script_dir = os.path.dirname(os.path.abspath(__file__))
font_file = os.path.join(script_dir, '..', '..', 'fonts', 'BabelStoneHan.ttf')
font_file = os.path.normpath(font_file)  # 規範化路徑

2. 顯式新增字型(最關鍵!)

# ❌ 錯誤:直接建立 FontProperties
font_prop = fm.FontProperties(fname=font_file)

# ✅ 正確:先 addfont,再建立 FontProperties
fm.fontManager.addfont(font_file)  # 關鍵!
font_prop = fm.FontProperties(fname=font_file)

3. 設定全域性字型

# 設定全域性字型
plt.rcParams['font.family'] = font_prop.get_name()
plt.rcParams['axes.unicode_minus'] = False  # 解決負號顯示問題

4. 使用絕對路徑

# ✅ 使用 os.path.normpath() 規範化路徑
font_file = os.path.normpath(font_file)

# ✅ 檢查檔案是否存在
if os.path.exists(font_file):
    fm.fontManager.addfont(font_file)

小蔥技能站7w4.net,專業的AI技能分享平臺。

5. 字型檔案在專案內

✅ 優點:
- 不依賴系統字型
- 可移植性好
- 跨平臺相容

❌ 避免:
- 使用系統字型路徑(/usr/share/fonts/...)
- 假設字型已安裝

🚨 常見問題

問題 1:中文顯示為方框

原因:沒有呼叫 addfont() 顯式新增字型

解決

# ✅ 必須先呼叫 addfont
fm.fontManager.addfont(font_file)
font_prop = fm.FontProperties(fname=font_file)

問題 2:負號顯示為方框

原因:字型不支援負號

解決

plt.rcParams['axes.unicode_minus'] = False

問題 3:字型路徑錯誤

原因:使用 os.getcwd() 而不是指令碼所在目錄

解決

# ✅ 使用指令碼所在目錄
script_dir = os.path.dirname(os.path.abspath(__file__))

問題 4:圖片已生成但中文仍是方框

原因:程式碼修改有誤或傳送了舊圖片

解決: 1. 刪除舊圖片:rm -f output.png 2. 重新執行指令碼 3. 檢查圖片修改時間:stat output.png | grep Modify


問題 6:'FontManager' object has no attribute 'addfont'

原因fontManager.addfont() 是 matplotlib 3.2+ 才有的方法

解決:使用版本相容性檢查

# 相容所有 matplotlib 版本
if hasattr(fm.fontManager, 'addfont'):
    # matplotlib 3.2+
    fm.fontManager.addfont(font_file)
else:
    # matplotlib < 3.2
    try:
        fm.fontManager.ttflist.append(fm.FontEntry(...))
    except Exception:
        pass

檢查 matplotlib 版本

import matplotlib
print(matplotlib.__version__)

問題 7:字型快取問題

原因:matplotlib 快取了舊字型配置

解決

# 清除字型快取
try:
    fm._load_fontmanager(try_read_cache=False)
except:
    pass

📊 對比總結

方案 優點 缺點 推薦度
字型檔案在專案內 可移植、跨平臺 需要管理字型檔案 ⭐⭐⭐⭐⭐
使用系統字型 無需管理檔案 依賴系統、不可移植 ⭐⭐
臨時下載字型 自動化 網路依賴、速度慢 ⭐⭐⭐

📁 Skill 包含內容

python-matplotlib-chinese-font/
├── SKILL.md                    # Skill 說明文件(本檔案)
├── references/
│   ├── plot_utils.py          # 完整工具模組
│   └── test_chinese_font.py   # 測試程式碼
└── templates/
    └── setup_font.py          # 配置模板(可直接複製)

⚠️ 字型檔案需自行下載,詳見"第 0 步:下載字型檔案"

📚 參考程式碼

完整工具模組references/plot_utils.py

  • ✅ 完整的字型配置函式
  • ✅ 可直接匯入使用
  • ✅ 包含常用繪圖引數

測試程式碼references/test_chinese_font.py

  • ✅ 4 種測試場景
  • ✅ 驗證中文顯示是否正常
  • ✅ 包含負數測試

配置模板templates/setup_font.py

  • ✅ 可直接複製到專案
  • ✅ 只需修改字型路徑

💡 最佳實踐

# ✅ 推薦配置
import os
import matplotlib.pyplot as plt
from matplotlib import font_manager as fm

# 1. 字型路徑(相對於指令碼)
_FONT_FILE_RELATIVE = os.path.join('..', '..', 'fonts', 'BabelStoneHan.ttf')

# 2. 獲取絕對路徑
def _get_font_path():
    script_dir = os.path.dirname(os.path.abspath(__file__))
    font_file = os.path.join(script_dir, _FONT_FILE_RELATIVE)
    return os.path.normpath(font_file)

# 3. 配置字型
def setup_chinese_font():
    font_file = _get_font_path()

    if os.path.exists(font_file):
        fm.fontManager.addfont(font_file)  # 關鍵!
        font_prop = fm.FontProperties(fname=font_file)
        plt.rcParams['font.family'] = font_prop.get_name()
        plt.rcParams['axes.unicode_minus'] = False
        return font_prop

    return fm.FontProperties()

# 4. 使用
chinese_font = setup_chinese_font()

🔗 相關連結

  • BabelStone Fonts: https://www.babelstone.co.uk/Fonts/Han.html
  • Matplotlib Font Management: https://matplotlib.org/stable/api/font_manager_api.html
  • Matplotlib Chinese Font Guide: https://matplotlib.org/stable/tutorials/text/text_intro.html

📝 版本歷史

版本 日期 說明
v1.0.0 2026-03-21 初始版本 - BabelStoneHan 字型配置方案
v1.1.0 2026-03-21 新增 matplotlib 版本相容性支援
v1.2.0 2026-04-02 字型檔案改為使用者自行下載(滿足 clawhub 檔案大小限制)

Skill 建立時間:2026-03-21
維護者:太子
當前版本:v1.2.0

📁 包含檔案 (5 個)

📄 SKILL.md 11.8 KB
📄 _meta.json 149 B
📄 references/plot_utils.py 9.3 KB
📄 references/test_chinese_font.py 6.5 KB
📄 templates/setup_font.py 5.5 KB