/cjk-viz
CJK (中日韩) 字体检测与 matplotlib 配置。任何涉及中文标签、标题、图例的 可视化任务启动前必须先执行本 skill 的字体检测流程,确保不会出现方块乱码。 适用于 matplotlib / seaborn / plotly 静态导出等场景。
$ npx -y skills add xjtulyc/MedgeClaw --skill cjk-viz --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/cjk-viz
Context preview
The summary Claude sees to decide when to auto-load this skill.
CJK (中日韩) 字体检测与 matplotlib 配置。任何涉及中文标签、标题、图例的 可视化任务启动前必须先执行本 skill 的字体检测流程,确保不会出现方块乱码。 适用于 matplotlib / seaborn / plotly 静态导出等场景。
SKILL.md
cjk-viz.SKILL.mdname: cjk-viz
description: >
CJK (中日韩) 字体检测与 matplotlib 配置。任何涉及中文标签、标题、图例的
可视化任务启动前必须先执行本 skill 的字体检测流程,确保不会出现方块乱码。
适用于 matplotlib / seaborn / plotly 静态导出等场景。
version: 1.0.0
metadata:
openclaw:
emoji: "🔤"CJK 可视化字体配置
何时使用
任何绘图代码中包含中文文本(标题、轴标签、图例、注释)时,**必须在绘图前** 执行字体检测。不要假设某个字体一定存在。
快速使用
方式一:导入 helper(推荐)
将 `scripts/setup_cjk_font.py` 复制到工作目录,或直接引用:
import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'skills/cjk-viz/scripts'))
from setup_cjk_font import setup_cjk_font
font_name = setup_cjk_font() # 自动检测、配置、返回字体名
# 如果返回 None,说明系统无可用 CJK 字体,会打印警告
调用后 `plt.rcParams` 已经配置好,直接绘图即可。
方式二:内联代码片段
如果不想引入外部文件,在脚本开头加入:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
def _setup_cjk():
candidates = [
'Noto Sans CJK SC', 'Noto Sans SC', 'Source Han Sans SC',
'WenQuanYi Micro Hei', 'WenQuanYi Zen Hei',
'Droid Sans Fallback', 'AR PL UMing CN',
'SimHei', 'Microsoft YaHei', 'PingFang SC',
]
available = {f.name for f in fm.fontManager.ttflist}
for name in candidates:
if name in available:
plt.rcParams['font.sans-serif'] = [name, 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
return name
# 尝试从常见路径加载 .ttf
search_paths = [
'/usr/share/fonts', '/usr/local/share/fonts',
os.path.expanduser('~/.local/share/fonts'),
os.path.join(os.path.dirname(__file__), 'fonts'),
]
for base in search_paths:
for root, _, files in os.walk(base):
for f in files:
if f.lower().endswith('.ttf') and any(
k in f.lower() for k in ['noto', 'cjk', 'hei', 'han', 'wenquan', 'droid']
):
path = os.path.join(root, f)
fm.fontManager.addfont(path)
prop = fm.FontProperties(fname=path)
name = prop.get_name()
plt.rcParams['font.sans-serif'] = [name, 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
return name
print("⚠️ 未找到 CJK 字体,中文可能显示为方块。")
print(" 安装建议: apt install fonts-noto-cjk 或 pip install matplotlib-cjk-fonts")
return None
_cjk_font = _setup_cjk()方式三:安装字体后再绘图
如果检测失败,在 Docker 容器内安装:
apt-get update && apt-get install -y fonts-noto-cjk
# 或者用 pip 安装打包好的字体
pip install matplotlib-cjk-fonts
安装后需要清除 matplotlib 字体缓存:
import matplotlib
import shutil, os
cache_dir = matplotlib.get_cachedir()
if os.path.exists(cache_dir):
shutil.rmtree(cache_dir)
print(f"已清除缓存: {cache_dir}")关键陷阱:`.ttc` 文件与 matplotlib
**这是最常见的坑。** 很多 Linux/Docker 环境安装的 CJK 字体是 `.ttc`(TrueType Collection) 格式(如 `NotoSansCJK-Regular.ttc`),matplotlib 能检测到但 `rcParams` 设置后不生效。
症状
- `setup_cjk_font()` 报告成功,但图片中文仍显示为方块 □□□
- `findfont()` 能找到字体文件,但渲染时不使用
解决方案:FontProperties 模式
对 `.ttc` 文件,必须用 `FontProperties(fname=path)` 显式传给每个文本元素:
from matplotlib.font_manager import FontProperties
# 全局 FontProperties 对象
CJK_FP = FontProperties(fname='/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc')
# 用法: 每个含中文的文本元素都要传 fontproperties=CJK_FP
ax.set_xlabel('中文标签', fontproperties=CJK_FP)
ax.set_ylabel('中文标签', fontproperties=CJK_FP)
ax.set_title('中文标题', fontproperties=CJK_FP)
ax.set_yticklabels(chinese_labels, fontproperties=CJK_FP)
# legend 需要特殊处理: prop= 设置条目字体, title 需要单独设置
ax.legend(title='中文图例标题', prop=CJK_FP)
ax.get_legend().get_title().set_fontproperties(CJK_FP)
# suptitle 同理
plt.suptitle('中文总标题', fontproperties=CJK_FP)优先级策略
1. **优先找 `.ttf` 文件** → 可以用 `rcParams` 全局设置,最省事 2. **只有 `.ttc` 文件** → 必须用 `FontProperties(fname=)` 逐个传参 3. **都没有** → 安装字体或用内嵌 `.ttf`
helper 脚本已内置此逻辑
`scripts/setup_cjk_font.py` 的 `setup_cjk_font()` 会优先找 `.ttf`, 找不到时返回 `.ttc` 路径。调用 `get_cjk_fp()` 获取 `FontProperties` 对象。
字体优先级
按以下顺序尝试(覆盖大多数 Linux / Docker / macOS 环境):
| 优先级 | 字体名 | 常见来源 | |--------|--------|----------| | 1 | Noto Sans CJK SC | `fonts-noto-cjk` (Debian/Ubuntu) | | 2 | Noto Sans SC | Google Fonts | | 3 | Source Han Sans SC | Adobe 思源黑体 | | 4 | WenQuanYi Micro Hei | `fonts-wqy-microhei` | | 5 | WenQuanYi Zen Hei | `fonts-wqy-zenhei` | | 6 | Droid Sans Fallback | Android / 旧版 Docker 镜像 | | 7 | AR PL UMing CN | `fonts-arphic-uming` | | 8 | SimHei | Windows | | 9 | Microsoft YaHei | Windows | | 10 | PingFang SC | macOS |
与其他 skill 配合
- 使用 `scientific-visualization` 或 `matplotlib` skill 时,先执行本 skill 的字体配置
- 使用 `plotly` 生成静态图片(`write_image`)时同样需要配置字体
- 在 `biomed-dispatch` 的 prompt 中可以加入:"绘图前先运行 cjk-viz 字体检测"
验证
绘图后可以用以下代码快速验证中文是否正常渲染:
fig, ax = plt.subplots(figsize=(4, 2))
ax.text(0.5, 0.5, '中文测试 Chinese Test 123',
ha='center', va='center', fontsize=16, transform=ax.transAxes)
ax.set_title('字体验证')
fig.savefig('/workspace/outputs/cjk_font_test.png', dpi=100, bbox_inches='tight')
print("✅ 验证图已保存,请检查中文是否正常显示")Read more
name: cjk-viz
description: >
CJK (中日韩) 字体检测与 matplotlib 配置。任何涉及中文标签、标题、图例的
可视化任务启动前必须先执行本 skill 的字体检测流程,确保不会出现方块乱码。
适用于 matplotlib / seaborn / plotly 静态导出等场景。
version: 1.0.0
metadata:
openclaw:
emoji: "🔤"CJK 可视化字体配置
何时使用
任何绘图代码中包含中文文本(标题、轴标签、图例、注释)时,**必须在绘图前** 执行字体检测。不要假设某个字体一定存在。
快速使用
方式一:导入 helper(推荐)
将 `scripts/setup_cjk_font.py` 复制到工作目录,或直接引用:
import sys, os sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'skills/cjk-viz/scripts')) from setup_cjk_font import setup_cjk_font font_name = setup_cjk_font() # 自动检测、配置、返回字体名 # 如果返回 None,说明系统无可用 CJK 字体,会打印警告
调用后 `plt.rcParams` 已经配置好,直接绘图即可。
方式二:内联代码片段
如果不想引入外部文件,在脚本开头加入:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
def _setup_cjk():
candidates = [
'Noto Sans CJK SC', 'Noto Sans SC', 'Source Han Sans SC',
'WenQuanYi Micro Hei', 'WenQuanYi Zen Hei',
'Droid Sans Fallback', 'AR PL UMing CN',
'SimHei', 'Microsoft YaHei', 'PingFang SC',
]
available = {f.name for f in fm.fontManager.ttflist}
for name in candidates:
if name in available:
plt.rcParams['font.sans-serif'] = [name, 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
return name
# 尝试从常见路径加载 .ttf
search_paths = [
'/usr/share/fonts', '/usr/local/share/fonts',
os.path.expanduser('~/.local/share/fonts'),
os.path.join(os.path.dirname(__file__), 'fonts'),
]
for base in search_paths:
for root, _, files in os.walk(base):
for f in files:
if f.lower().endswith('.ttf') and any(
k in f.lower() for k in ['noto', 'cjk', 'hei', 'han', 'wenquan', 'droid']
):
path = os.path.join(root, f)
fm.fontManager.addfont(path)
prop = fm.FontProperties(fname=path)
name = prop.get_name()
plt.rcParams['font.sans-serif'] = [name, 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
return name
print("⚠️ 未找到 CJK 字体,中文可能显示为方块。")
print(" 安装建议: apt install fonts-noto-cjk 或 pip install matplotlib-cjk-fonts")
return None
_cjk_font = _setup_cjk()方式三:安装字体后再绘图
如果检测失败,在 Docker 容器内安装:
apt-get update && apt-get install -y fonts-noto-cjk # 或者用 pip 安装打包好的字体 pip install matplotlib-cjk-fonts
安装后需要清除 matplotlib 字体缓存:
import matplotlib
import shutil, os
cache_dir = matplotlib.get_cachedir()
if os.path.exists(cache_dir):
shutil.rmtree(cache_dir)
print(f"已清除缓存: {cache_dir}")关键陷阱:`.ttc` 文件与 matplotlib
**这是最常见的坑。** 很多 Linux/Docker 环境安装的 CJK 字体是 `.ttc`(TrueType Collection) 格式(如 `NotoSansCJK-Regular.ttc`),matplotlib 能检测到但 `rcParams` 设置后不生效。
症状
- `setup_cjk_font()` 报告成功,但图片中文仍显示为方块 □□□
- `findfont()` 能找到字体文件,但渲染时不使用
解决方案:FontProperties 模式
对 `.ttc` 文件,必须用 `FontProperties(fname=path)` 显式传给每个文本元素:
from matplotlib.font_manager import FontProperties
# 全局 FontProperties 对象
CJK_FP = FontProperties(fname='/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc')
# 用法: 每个含中文的文本元素都要传 fontproperties=CJK_FP
ax.set_xlabel('中文标签', fontproperties=CJK_FP)
ax.set_ylabel('中文标签', fontproperties=CJK_FP)
ax.set_title('中文标题', fontproperties=CJK_FP)
ax.set_yticklabels(chinese_labels, fontproperties=CJK_FP)
# legend 需要特殊处理: prop= 设置条目字体, title 需要单独设置
ax.legend(title='中文图例标题', prop=CJK_FP)
ax.get_legend().get_title().set_fontproperties(CJK_FP)
# suptitle 同理
plt.suptitle('中文总标题', fontproperties=CJK_FP)优先级策略
1. **优先找 `.ttf` 文件** → 可以用 `rcParams` 全局设置,最省事 2. **只有 `.ttc` 文件** → 必须用 `FontProperties(fname=)` 逐个传参 3. **都没有** → 安装字体或用内嵌 `.ttf`
helper 脚本已内置此逻辑
`scripts/setup_cjk_font.py` 的 `setup_cjk_font()` 会优先找 `.ttf`, 找不到时返回 `.ttc` 路径。调用 `get_cjk_fp()` 获取 `FontProperties` 对象。
字体优先级
按以下顺序尝试(覆盖大多数 Linux / Docker / macOS 环境):
| 优先级 | 字体名 | 常见来源 | |--------|--------|----------| | 1 | Noto Sans CJK SC | `fonts-noto-cjk` (Debian/Ubuntu) | | 2 | Noto Sans SC | Google Fonts | | 3 | Source Han Sans SC | Adobe 思源黑体 | | 4 | WenQuanYi Micro Hei | `fonts-wqy-microhei` | | 5 | WenQuanYi Zen Hei | `fonts-wqy-zenhei` | | 6 | Droid Sans Fallback | Android / 旧版 Docker 镜像 | | 7 | AR PL UMing CN | `fonts-arphic-uming` | | 8 | SimHei | Windows | | 9 | Microsoft YaHei | Windows | | 10 | PingFang SC | macOS |
与其他 skill 配合
- 使用 `scientific-visualization` 或 `matplotlib` skill 时,先执行本 skill 的字体配置
- 使用 `plotly` 生成静态图片(`write_image`)时同样需要配置字体
- 在 `biomed-dispatch` 的 prompt 中可以加入:"绘图前先运行 cjk-viz 字体检测"
验证
绘图后可以用以下代码快速验证中文是否正常渲染:
fig, ax = plt.subplots(figsize=(4, 2))
ax.text(0.5, 0.5, '中文测试 Chinese Test 123',
ha='center', va='center', fontsize=16, transform=ax.transAxes)
ax.set_title('字体验证')
fig.savefig('/workspace/outputs/cjk_font_test.png', dpi=100, bbox_inches='tight')
print("✅ 验证图已保存,请检查中文是否正常显示")Open-source AI research assistant for biomedicine — chat to run RNA-seq, drug discovery, clinical analysis, and more. Built on Claude Code with 140 K-Dense scientific skills, real-time dashboard, and RStudio/JupyterLab integration. | 开源生物医学 AI 研究助手,对话即可驱动转录组、药物发现、临床分析等工作流,集成 140 个科学技能与实时研究看板。

