Install
openclaw skills install @bo170814/html-cn-render-fixFix Chinese and emoji rendering issues in Python-generated images by explicitly loading and applying compatible fonts with matplotlib's FontProperties.
openclaw skills install @bo170814/html-cn-render-fix解决 Python 生成图片时中文显示为方框/乱码的问题
在使用 matplotlib、pyppeteer 等工具生成包含中文的图片时,经常遇到:
from matplotlib.font_manager import FontProperties
# 直接加载字体文件
font_path = '/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc'
font_prop = FontProperties(fname=font_path)
# 在每个文本渲染处使用
fig.suptitle('中文标题', fontsize=16, fontproperties=font_prop)
ax.set_xlabel('X 轴标签', fontproperties=font_prop)
ax.set_ylabel('Y 轴标签', fontproperties=font_prop)
ax.annotate('标注文字', xy=(x, y), fontproperties=font_prop)
# 设置图例
leg = ax.legend()
for text in leg.get_texts():
text.set_fontproperties(font_prop)
# 设置坐标轴标签
for label in ax.get_xticklabels():
label.set_fontproperties(font_prop)
优点:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Noto Sans CJK SC', 'SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
缺点:
某些 emoji(特别是国旗 emoji 🇨🇳🇺🇸)在某些系统中不支持:
# ❌ 避免使用
title = "🇨🇳 中国股票"
# ✅ 使用文字代替
title = "中国股票"
# ✅ 或使用通用 emoji
title = "📈 中国股票" # 图表 emoji 兼容性更好
#!/usr/bin/env python3
"""
HTML 转图片中文无乱码示例
"""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import io
import base64
# 加载字体文件
font_path = '/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc'
font_prop = FontProperties(fname=font_path)
font_prop_title = FontProperties(fname=font_path, size=16, weight='bold')
font_prop_label = FontProperties(fname=font_path, size=12)
# 创建图表
fig, ax = plt.subplots(figsize=(10, 6))
fig.suptitle('中文标题示例', fontsize=16, fontproperties=font_prop_title)
# 绘制数据
ax.plot([1, 2, 3, 4], [1, 4, 2, 3], label='数据曲线')
# 设置标签(使用 fontproperties)
ax.set_xlabel('X 轴', fontsize=12, fontproperties=font_prop_label)
ax.set_ylabel('Y 轴', fontsize=12, fontproperties=font_prop_label)
ax.set_title('图表标题', fontsize=12, fontproperties=font_prop_label)
# 设置图例
leg = ax.legend()
for text in leg.get_texts():
text.set_fontproperties(font_prop)
# 设置坐标轴刻度标签
for label in ax.get_xticklabels():
label.set_fontproperties(font_prop)
for label in ax.get_yticklabels():
label.set_fontproperties(font_prop)
# 添加标注
ax.annotate('最高点', xy=(2, 4), xytext=(2.5, 4.5),
fontproperties=font_prop,
arrowprops=dict(arrowstyle='->'))
# 保存为 base64
buf = io.BytesIO()
plt.savefig(buf, dpi=100, bbox_inches='tight', format='png')
buf.seek(0)
img_base64 = base64.b64encode(buf.read()).decode('utf-8')
plt.close()
print(f"✅ 生成成功!图片大小:{len(img_base64)} bytes")
# 安装 Noto CJK 字体
apt-get install fonts-noto-cjk -y
# 或安装文泉驿字体
apt-get install fonts-wqy-microhei fonts-wqy-zenhei -y
# 安装 Noto CJK 字体
yum install google-noto-sans-cjk-fonts -y
# 或安装文泉驿字体
yum install wqy-microhei-fonts wqy-zenhei-fonts -y
# 使用 Homebrew
brew install --cask font-noto-sans-cjk
# 查看已安装的中文字体
fc-list :lang=zh
# 查看特定字体
fc-list | grep -i "noto\|cjk\|wenquanyi"
# 测试字体
fc-match "Noto Sans CJK SC"
A: 确保:
fontproperties=font_proprm -rf ~/.cache/matplotlibA: 避免使用复杂 emoji(特别是国旗 emoji),改用:
A: 首次运行会加载字体,后续会使用缓存。可以预加载字体:
from matplotlib import font_manager
font_manager.fontManager.addfont(font_path)
~/.cache/matplotlib许可证: MIT
版本: 1.0.0