# Biofigure Self Evolve

> 生物信息学 figure 的学习库与复用引擎：把文献、PDF、公众号文章、截图里的图解剖成可复用的画法（图表配方 + R/Python 双模板），存入本地自进化图库；材料带代码线索（GitHub 仓库、正文内嵌代码、论文 code availability）时必先追溯原始绘图代码作为配方事实源；用户做生信数据分析要画图时（无论明确点名图型，还是分析完成后需要呈现结果），先检索图库复用已学会的画法，相似候选多个时给出差异对比与推荐，没有才从头设计。Use whenever the user sends papers, PDFs, WeChat 公众号 article links, or figure screenshots containing plots, asks to learn a figure (学一下这个图 / 入库 / 记住这个画法), asks to replicate a figure's style (照这张图画 / 按文献风格复刻), wants any bioinformatics/biostatistics chart (heatmap, volcano, KM survival, boxplot, enrichment dotplot, oncoprint, Venn/UpSet, circos, Manhattan, UMAP/t-SNE, forest, ROC…), or asks what figures the library already knows (看看图库/你都会画什么图) — even if the user does not mention "figure 库".

- Skill: `zessi-c/biofigure-self-evolve` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add zessi-c/biofigure-self-evolve`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zessi-c/biofigure-self-evolve/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: Zessi-C (https://skillmd.com/u/zessi-c)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/zessi-c/biofigure-self-evolve

---


# Biofigure Memory — 生信 figure 学习库与复用引擎

本技能维护一个**自进化**的个人图库：把用户发来的文献图（论文 PDF、链接、公众号文章、截图）解剖成「语言无关的绘制配方 + R/Python 可运行模板」沉淀下来；等用户真正要画图时，优先复用库里已学会的画法，而不是每次从零设计。用户对复用结果满意时，再把这次的画法回收入库，形成闭环。

技能只有两个模式，按用户意图选择：

- **模式 A 学习**（ingest）：用户发来了含 figure 的材料 → 解剖、沉淀入库。
- **模式 B 复用**（reuse）：用户要画一张生信图 → 先查图库，命中就复用，未命中就走普通设计流程，满意后顺势提议入库。

## 核心心法：参考模仿，不是一比一照抄

图库条目是**画法参考**，不是可直接调用的成品管线。每次用户的数据结构、组数、目的都不同，所以：

- 复用时提取的是条目的**技术骨架**（图层组织、映射方式、配色逻辑、排版策略、注释手段），其余一切——轴、阈值、色值、分面数、面板构成、尺寸——都按用户当前数据和目的重新决定。用户的目的优先于记录里的任何细节
- 允许**部分借用**：条目与需求只有局部相似时，就只借那一部分（比如只学它的标签防重叠策略、或只学它的行序联动设计），不要硬套整张图
- 学习时也要以这个标准写记录：配方写到「技术」层面而非「参数」层面（记"qualitative 色板 + 密度中心标编号"，不要记"必须 8 个群用这 8 个色号"）。原稿的具体数值只作为缺省建议写入复用要点
- 简单说：把条目当「范帖」临摹，不当「模板」填空。交付语也应体现这一点（"参考了 003 的高亮画法，配色/分组按你的数据重排了"），而不是"调用了 003"

## 触发场景与预期行为

对照下表选择行为；「主动问」仅限交互环境，非交互环境一律取该行「不打扰」侧的行为：

| 场景 | 预期行为 |
|---|---|
| 明确要求学习/入库（"学一下这个图""记住这个画法"），材料为链接/PDF/公众号/截图 | 模式 A，直接执行，不再确认 |
| 用户发来文献材料但未提学习，材料中有值得学的 figure | 一句话问是否入库（例："Fig.3 的点图画法不错，入库吗？"）；非交互不打扰 |
| 明确要求画生信图（点名图型或描述意图，如"生存分析画条曲线"） | 模式 B，先查库再动手 |
| 数据分析任务隐含出图需求（如差异分析跑完需要呈现结果） | 结果呈现前查库；命中按复用流程，未命中正常设计 |
| "照这张图画 / 按这篇文献风格复刻"（给了参考图或文献） | 参考图即规格：先按模式 A 学习它（这就是明确意图，无需再问），再按其配方对用户数据出图 |
| 用户对刚交付的图表示满意 | 提议入库（manual 来源），同意即走模式 A |
| 用户问"你都会画哪些图 / 看看图库" | 读 INDEX.md，按 chart_types 分组展示，不逐条展开 |
| 用户要求把条目发到别的设备（"把 003 发给服务器"）或导入一个 bundle 包 | 跨设备导出/导入：导出跑 `export_figure.py`，导入跑 `import_figure.py`，直接执行（见「跨设备导出/导入」节） |

**不触发的边界**（防止过度打扰与错误接管）：

- 纯文献阅读、翻译、总结，用户没有表现出任何画图/学习意图 → 不主动提入库
- 用户已给出完整明确的绘图代码或参数 → 照做，不往图库上套
- 与生物/医学数据无关的通用图表（商业图表、装饰性插图等）→ 本技能不接管，走正常画图流程

## 图库位置

图库**内嵌在技能目录下**（`<本技能目录>/library/`），与技能是同一个文件夹——把整个技能目录拷贝/同步到任何设备的任何 agent 的技能目录，技能与图库同时就位，无需任何配置。图库是纯文件，建议对技能目录做 git 版本管理（防误删，同步也有历史）。跨设备有两条路线：整库双向同步（私有 git 仓库或云盘），或按条目细粒度迁移（见「跨设备导出/导入」节）。

仅当用户明确要求把图库放在别处时，按以下顺序解析（脚本端同样遵守）：

1. 环境变量 `BIOFIGURE_LIBRARY`
2. `~/.config/biofigure-self-evolve/config.json` 中的 `library_path` 字段
3. 回落到默认位置 `<技能目录>/library/`

图库结构（`NNN` 为三位递增序号，slug 用小写连字符英文）：

```text
<技能目录>/
├── SKILL.md
├── library/                # 图库（与技能一起同步）
│   ├── README.md
│   ├── INDEX.json          # 机器可读索引，复用时先读这个
│   ├── INDEX.md            # 人类可读索引，由脚本生成
│   └── figures/
│       └── 001-volcano-pathway-labels/
│           ├── figure.md       # 学习记录：元数据 + 视觉解剖 + 配方（库的核心）
│           ├── reference.png   # 原图（≤1600px 宽、<2MB）
│           ├── template.R      # 自包含 R 模板，内嵌假数据，无参数运行即可出图
│           └── template.py     # 自包含 Python 模板，同上
├── references/
└── scripts/
```

## 交互策略（先读这段）

每次进入任一模式前，先判断会话类型，行为随之固定：

**交互环境**（用户在场、可以提问）：

- 学习：用户**明确要求**学习/入库 → 直接做，不再确认。用户只是发来材料没提学习 → 判断材料里是否有值得学的 figure，有则用一句话问（例：「Fig.2a 的富集点图画法不错，要入库学习吗？」），得到肯定才学。
- 复用：图库命中**唯一且高置信** → 直接用，并在交付时说明用了哪条记录；有**多个候选或置信不足** → 一次性列出候选（每条一行：id + 一句话区别），给出推荐项，让用户选。只在此时问，之后执行不再追问。

**非交互环境**（后台任务、管道、自动化流程、用户已声明不要询问）：**永远不要等待用户输入**。

- 学习：仅在用户明确要求时执行；材料里没被要求学习的图不主动入库。
- 复用：选最匹配的一条直接画，把「用了图库哪条记录、基于什么假设做的适配」写进最终交付说明里。

## 模式 A：学习新 figure

### A0 查重与归位（相似功能图的处理）

生信图大量"同功能、不同形"：火山图、MA 图、显著性条形图都在"展示两组差异"；KM 曲线、风险评分图、森林图都在"展示预后"。**判断近似的标准是"用户要它回答什么问题"，不是表面图类型。** 学习前先读 `INDEX.json`，找出与新材料功能近似的已有条目（chart_types 相同、或 use_when 语义相近），然后三选一：

- **更新已有条目**：新材料是同一画法的更清晰版本或细节补充 → 合并进旧条目（交互环境先问；非交互环境在新旧明显同款时默认更新）
- **登记为变体**：核心画法相同但有实质差异（如带风险表的 KM vs 纯 KM 曲线）→ 新建条目，新旧双方 frontmatter 互写 `related`，并各自在正文「与相近条目的对比」一句话写清何时用谁——这是复用时多候选排序的依据
- **独立条目**：仅图类型撞名、回答的问题确实不同 → 正常新建

宁可多建带 `related` 的变体条目，也不要把不同画法硬塞进一条记录里稀释配方精度。

### A1 获取图像并确定学习单元

按材料类型取图，具体命令和各平台的坑见 `references/ingest-sources.md`（读取该文件后操作）：

- 本地图片/截图 → 直接用
- PDF → pdftoppm 把对应页转成 PNG 再裁剪面板
- 文献链接/DOI → 优先走 PMC/出版社页面找开放获取的图片 URL
- 微信公众号链接 → 抓 HTML 里的 `mmbiz.qpic.cn` 图片

**追溯原始代码（材料有代码线索时必做——代码是配方的事实源，图像只是间接证据）**：

1. **正文内嵌代码** → 直接作为一手配方（公众号教程常整段贴码，抓 HTML 时连正文文本一起提取）
2. **文中提到 GitHub 仓库** → GitHub API 列文件树找绘图脚本（`api.github.com/repos/<user>/<repo>/git/trees/main?recursive=1`，脚本名常含 fig/plot），raw 拉取（`raw.githubusercontent.com/...`）
3. **只给了论文** → 先解 DOI，WebFetch 其 PMC 全文的 "Data and code availability" 找仓库 URL，回到第 2 步
4. **穷尽 1-3 未果** → 才回到看图反推，并在记录 source.ref 如实标注"代码未溯源，配方由图像解剖得出"

包名、几何对象、参数、数据整形一律以代码为准（实例：Fig.1E 肉眼看像 ggalluvial，代码揭示是 ggsankey）。细节命令见 `references/ingest-sources.md` 第 6 节。

**取到图后，先判断图与图之间的关系，再决定学习单元的粒度**——生信文献图的新意往往不在单图，而在组合与成对叙事。三种粒度：

1. **单图条目**：一个独立图表类型的画法（如一张编号 UMAP）
2. **组合版式条目**：多子图拼接本身是亮点（如 UMAP 纵列 + dotplot + 热图并排）→ 条目核心是「面板联动」：行序/列序/配色/编号在面板间如何共享，必须逐条写清
3. **图序模式条目**：多张图作为一组讲一个故事（如「总览编号 UMAP 的群编号 = 详情组图的行索引」，总览图的价值正在于此）→ 把成对/成组的图拼成一张 reference，条目记录叙事分工与联动关系

判断口诀：删掉其中一张图、另一张的信息是否受损？受损 → 这是图序模式；单独都成立但并排更强大 → 组合版式；完全独立 → 各自成条目并用 `related` 互链。同一材料里被选中学习的是什么、没学的是什么，汇报时逐图说明（见 A8）。

### A2 解剖

用 Read 查看图像，小面板先裁剪放大成局部图再读，逐面板回答：

1. **图类型**：对照 `references/chart-taxonomy.md` 的受控词表打 `chart_types` 标签
2. **数据形状**：这张图需要什么样的输入（宽矩阵/长表/成对/邻接表…）
3. **图层与映射**：从底到顶有哪些图层，x/y/color/size/fill 各映射了什么
4. **坐标与变换**：log 轴、反转、极坐标、分面等
5. **配色与排版**：离散/连续色板、图例位置、尺寸比例、字号、导出规格
6. **适用范围**：什么场景该用它（use_when）、什么场景不该（not_when）——这是复用时匹配的关键字段，写具体

### A3 写学习记录

图库根目录下新建 `figures/NNN-slug/`，写 `figure.md`。**格式 schema 和完整示例必须先读 `references/figure-record.md`**，frontmatter 只使用其中定义的字段和受限语法（不用多行块、锚点等复杂 YAML，保证任何设备任何工具都能解析）。正文包含：视觉解剖、语言无关配方、模板自检记录、复用要点。

解剖保持客观：若用户在学习时当场表达风格意见（"这种配色我不喜欢"），那是偏好信号，写进 `library/PREFERENCES.md`，不要因此歪曲对原图的记录。

### A4 写双语言模板并自检

`template.R` 与 `template.py` 各写一份，要求：

- **自包含**：脚本内嵌生成符合 data_shape 的逼真假数据，无参数运行即出图（PNG 300dpi + PDF 矢量各一份，输出到脚本所在目录）
- 结构与 figure.md 里的配方一一对应，中文注释关键步骤；复用时用户只需要替换数据载入段
- 语言按图的特点选最顺手的实现：R 用 ggplot2 生态（ComplexHeatmap、patchwork 等），Python 用 matplotlib/seaborn 生态；两份模板功能对等
- **实际运行验证**：`Rscript template.R`、`python3 template.py`，确认能出图。通过 → frontmatter `verified: both`；只有一边的运行时可用或某边失败 → 如实标 `partial` 或 `unverified`，并在正文「模板自检记录」写明原因。宁可如实标注，不要标记未验证的条目为通过

### A5 保存原图

原图或裁剪后的面板存为 `reference.png`，用 sips 或 PIL 缩到宽 ≤1600px、<2MB（图库要跨设备同步，大图会拖慢 git/云盘）。仅作个人本地学习参考；若日后要公开分享图库，注意原文献版权。

### A6 完工自检（学习要点清单）

写完记录和模板后，逐项核对下面的清单。**这是学习完成的最低标准——缺任何一项就不算学完，不得进入汇报**。清单存在的意义：模型容易"看懂了"就宣布学完，实际漏掉的恰恰是复用时最需要的信息。

1. **回答什么问题**：use_when 写到了"用户拿它回答什么"，不是图名复述
2. **数据形状**：读者只看 data_shape 一行，就能判断自己的表能不能套
3. **图层解剖可复现**：每层画什么、映射、顺序、参数量级——不看原图也能照配方写出代码
4. **配色具体**：色值或色板名，不是"红蓝配色"
5. **排版规格**：尺寸比例、字号层级、图例位置、导出规格
6. **联动关系**（组合/图序条目必查）：面板间共享的行序、列序、配色、编号逐条写明
7. **边界与坑**：not_when 写了误用场景；已知坑写了真实易错点
8. **关系登记**：`related` 与近似条目互指，对比句写清"何时用谁"
9. **模板可运行**：R/Python 双模板均实际运行出图，verified 如实标注
10. **原图可溯**：reference.png 已存且 <2MB；source 五字段齐全可溯源
11. **代码溯源**（材料有代码线索时必查）：原始代码已追溯并以代码校准配方（包名/参数/整形逻辑）；穷尽路径未果的，source.ref 已如实标注"代码未溯源"

### A7 更新索引

`figure.md` 是唯一事实源，索引文件是它的投影：运行 `python3 <skill目录>/scripts/build_index.py` 全量重建 `INDEX.json` 和 `INDEX.md`（不要手改这两个文件），并留意脚本输出的警告（缺字段、id 与目录名不一致、related 悬空等），有则回改 figure.md。

### A8 汇报

汇报三件事：**逐图取舍**——材料里每张图，学了什么条目、没学的原因（装饰图/常规画法/与已学重复，判断要具体，"常规画法"这种否决必须给出理由，警惕低估组合与成对叙事的价值）；**学到什么**——条目 id + 一句话；**验证状态**——模板运行情况、存到哪。

## 模式 B：复用画图

### B1 检索

读 `INDEX.json`（缺失、或 `python3 <技能目录>/scripts/build_index.py --check` 报不一致时，先跑 `build_index.py` 重建）和 `library/PREFERENCES.md`（若存在）。索引用语义匹配而非纯关键词：综合 `chart_types` + `data_shape` + `use_when`/`not_when` + `aliases` 判断哪条记录符合用户当前的数据和意图；偏好档案记录着用户跨会话的稳定习惯，供 B3 实例化时填充其未指定的细节。

### B2 多候选排序与选择

同功能的条目常有多条同时命中（这正是 A0 里 `related` 变体群的场景），按下述优先级排序后处理：

1. **数据形状匹配度**：用户的表能直接套 > 稍作整形能套 > 结构差异大
2. **意图匹配度**：use_when 命中用户要回答的问题；not_when 是否触雷
3. **verified 状态**：both > partial > unverified

- 交互环境：列 **top ≤3** 候选，每条一行「id + 与其他候选的一句关键差异」（信息优先来自条目的「与相近条目的对比」节），给出推荐及理由，等用户选。不要把全部命中一次甩出来
- 非交互环境：直接用第 1 名，交付时注明"另有 `NNN-xxx` 也适用，因 XX 选了本条"

### B3 临摹式适配（不是套模板）

打开命中条目的 `figure.md`（重点看「配方」「复用要点」「与相近条目的对比」三节），以配方为骨架、以用户数据和目的为准绳重画，而不是把用户数据塞进模板：

1. **先核对再动手**：复用要点里的检查项（列名、分组列、阈值习惯、标签列是否存在）逐项对照用户数据
2. **缺什么补什么**：数据形状不符时先整形到配方要求的形状；用户没有配方假定的某列（如通路注释列）时，降级到该画法的无此注释变体，并告诉用户差在哪
3. **按目的裁剪**：用户目的与条目 use_when 有偏差时，只借用的确服务当前目的的部分（借图层结构、借配色逻辑、借联动设计……），其余按需取舍
4. **取值优先级**：用户当前指令 > 稳定偏好（`PREFERENCES.md`）> 条目缺省——用户没指定的细节（阈值、配色、图例位置、导出规格）先用稳定偏好填充，没有稳定偏好才用条目缺省
5. **交付说明借用关系**：说明"参考了 `NNN-slug` 的哪些方面、按你的数据改了哪些"，让用户知道哪些结果是临摹、哪些是适配决策

### B4 交付与进化

- 交付时注明：复用了 `NNN-slug`、做了哪些适配假设
- **按反馈进化条目**（用户对这张图**画法本身**的反馈——无论是想改还是提了更好的做法）：回到**图库条目**落实，而不是只改一次性代码：
  - **画法级反馈**（图例位置、标签密度、配色体系、阈值/字号/尺寸缺省……）→ 直接改 `template.R` / `template.py` 的缺省值，同步更新该条目「配方」「复用要点」，**重跑双模板自检**，并在 figure.md 的「演化记录」追加一行：日期 + 反馈 + 改了什么
  - **数据级反馈**（"这批数据阈值要用 2"）→ 不动模板缺省，写进「复用要点」的变体或坑
  - 跨条目通用的习惯 → 同时写 `library/PREFERENCES.md`（见下条）；改完条目后重建索引
- **写回偏好**（跨图习惯，"图库越长越像你"的另一机制）：凡观察到合法偏好信号——用户明确的适配选择（"阈值用 1.5"）、对成图的反馈（"图例放上面"）、主动声明的习惯（"以后都要 PDF"）——按 `references/preference-profile.md` 追加进 `library/PREFERENCES.md`（先记单次观察，≥2 次一致晋升稳定偏好）。只记可观察信号，禁止脑补；没有信号就不写
- **未命中**：按普通流程从头设计这张图（不要硬套相近条目），正常交付。交付后若用户表示满意，主动提议：「要不要把这次的画法入库？」→ 走模式 A 沉淀（source.type=manual，ref 记本次任务描述；manual 条目的 reference.png 存**交付的成图**，没有原文献图）。这是图库进化的主要入口之一

## 跨设备导出/导入

典型场景：在个人电脑读文献学图，在服务器上跑分析时用。条目以单文件 **bundle**（zip，内含清单与逐文件 sha256）迁移；技能只管打包与解包，传输用 scp / rsync 等任意手段。

**导出**（在学会条目的设备上）：

```bash
python3 <技能目录>/scripts/export_figure.py 003                 # 数字前缀或完整 id，可多个，可用 all
python3 <技能目录>/scripts/export_figure.py 004 --with-related  # 连同 related 互指的条目一起打包
# --with-preferences 附带 PREFERENCES.md；template_output_* 验证产物默认不入包
```

**导入**（在目标设备上）：

```bash
python3 <技能目录>/scripts/import_figure.py bundle.zip --list   # 先预览包内容
python3 <技能目录>/scripts/import_figure.py bundle.zip          # 校验完整性后导入，自动重建索引
```

冲突策略（目标已有同 id 条目）：内容一致 → 跳过；内容不同 → 默认拒绝并提示，加 `--force` 覆盖，或 `--rename` 分配新编号（自动改写 frontmatter 的 id 与同批条目间的 related 互指）。非交互环境遇冲突跳过该项、继续导入其余条目。`--dry-run` 只走校验与判定不写盘。

导入后两件事：

- **体检**：目标环境可能与学图时的机器不同（缺 R 包等），跑 `python3 <技能目录>/scripts/verify_library.py` 把各模板复制到临时目录试运行；它只出报告不改图库，失败的条目按其报告处理（补依赖重跑，或更新 figure.md 的 verified 与「模板自检记录」）
- **偏好档案**：包内若带 PREFERENCES.md 而目标已有同名文件，脚本不覆盖——散文式合并由 agent 对比两份文件手工完成

## 维护

- `scripts/init_library.py [--path DIR]`：初始化图库骨架（幂等）；用 `--path` 指定非默认位置时自动写入 `~/.config/biofigure-self-evolve/config.json`
- `scripts/build_index.py [--library DIR]`：扫描所有 `figures/*/figure.md`，重建 INDEX.json + INDEX.md（无 PyYAML 也能跑），并告警缺字段、id 与目录名不一致、related 悬空、languages 与模板文件不符、reference.png 缺失或超 2MB；手动改过 figure.md 后运行
- `scripts/build_index.py --check`：只比对索引与记录是否一致（不一致退出码 1），不写文件；模式 B 检索前的快速新鲜度判定
- `scripts/export_figure.py <id...>` / `scripts/import_figure.py <bundle.zip>`：跨设备迁移条目，见「跨设备导出/导入」节
- `scripts/verify_library.py`：把各条目模板复制到临时目录试运行，只报告 pass / fail / skip，不改图库；条目导入新环境后跑一遍
- 手动修改记录后必须重跑 build_index.py——figure.md 是唯一事实源，索引只是投影
- 跨设备：整库双向同步用私有 git 仓库或云盘（整个技能目录含 library/ 一起同步即可）；按条目单向迁移用 export/import 脚本。不依赖 ZCode 或任何特定 agent 的特性
- `library/PREFERENCES.md` 是用户个人数据：公开分发图库时排除它（示例仓库的 .gitignore 已配置），私有同步仓库随库走
- 新增条目编号取现有最大 NNN + 1；删除条目时连同目录一起删并重建索引，不要复用旧编号；删除后记得把其他条目 `related` 里指向它的引用清掉（build_index.py 会对此告警）

## 参考文件

| 文件 | 何时读 |
|---|---|
| `references/figure-record.md` | 模式 A 写记录前、模式 B 需要看字段含义时（必读） |
| `references/ingest-sources.md` | 模式 A 第一步取图前（必读） |
| `references/chart-taxonomy.md` | 模式 A 打标签、模式 B 检索匹配时 |
| `references/preference-profile.md` | 模式 B 读写 `PREFERENCES.md` 前 |

