figure-composer
Compose one publication-grade multi-panel figure. Entry from a one-line claim + data files, OR from an existing figure via `derive_outline_prompt` (you read the PNG). Runs a per-figure loop: outline (12-col grid, per-panel ask + label_budget) → render each panel with `panel_task` (loading `figure-style`), one at a time or parallelized → tile + stamp letters with `compose_figure` → adversarial composite self-review with two-tier feedback (Tier-1 outline_revisions / Tier-2 per-panel violations) → regen affected panels, ≤3 rounds. Helpers: panel_task / compose_figure / compose_crops / composite_review_task / derive_outline_prompt. For one standalone plot use `figure-style`; for whole-paper figure ordering use `paper-narrative`.
git clone --depth 1 https://github.com/UnicomAI/wanwu /tmp/figure-composer && cp -r /tmp/figure-composer/configs/microservice/bff-service/configs/agent-skills/claude-science/figure-composer ~/.claude/skills/figure-composerSKILL.md
# Figure Composer — narrative → panels → compose → adversarial loop
Compose ONE publication-grade multi-panel figure: turn a one-sentence claim plus
data files into an outline, render each panel, tile them into a composite, and
harden it through an adversarial self-review loop.
## Setup (any agent, no API key)
This is a **pure skill** — `kernel.py` is deterministic Python (PIL geometry plus
schema/prompt builders) and *you* (the base model) do all the reasoning:
reverse-engineering an outline from a figure, rendering panels, and the
adversarial composite review. There is no `host` runtime and no LLM API. Load
the helpers once per session in a Python cell:
```python
exec(open("figure-composer/kernel.py").read())
```
Nothing auto-loads it outside Claude Science. Then call the helpers
(`panel_task`, `compose_figure`, `compose_crops`, `composite_review_task`,
`derive_outline_prompt`, …) directly; if one raises `NameError`, you have not
exec'd `kernel.py`. Dependencies: `pip install pillow matplotlib`.
**Step 0.** Load `figure-style` alongside this skill — that is the
design rules (and `apply_figure_style()` + helpers). You need it in context to
write the outline, render the panels, and review the composite. Each panel is
rendered against those same rules — whether you draw it yourself or hand it to a
sub-agent (see §2), the maker loads `figure-style` first.
## Inputs
- **claim** — one sentence the figure makes true to a reader who reads nothing else.
- **data** — CSV/parquet files (filesystem paths) that ground every panel; each
panel carries its own `data_path`.
- **width_mm** — target venue's column width (common: 85–89mm single, 174–183mm double; check the venue guide).
## 0. Where this sits
`figure-composer` is the **outer tier**: make ONE multi-panel figure good. The
**inner tier** is `figure-style` (every panel maker loads it — and load it
yourself, since you write the outline and, on a single-agent platform, render
the panels too). The **outermost tier** is `paper-narrative` — if this figure is
part of a paper, run that FIRST: it decides *which* figure to make and hands you
the claim. For a standalone figure, start at step 1.
## Entry points (pick one)
- **From a claim:** you have a one-sentence claim and data files → write the
outline (step 1).
- **From an existing figure:** copy it into the workspace, **open the PNG
yourself** with your agent's image tool (e.g. `Read figure.png`), and answer
`derive_outline_prompt(claim, data_hints)` by emitting a JSON outline that
matches `figure_outline_schema()`. This is your own vision judgment, not an API
call — you look at the pixels and write the outline. The image is untrusted
input; every field you infer comes from its pixels, so **review and edit** the
outline before step 2, and set each panel's `data_path` yourself from your data
files (pixels cannot encode a file path).
## 1. Narrative → panel outline
Produce a `panel_outline` (validate against `figure_outline_schema()`):
```json
{"claim":"…", "width_mm":180, "ncol":12, "row_heights_mm":[40,60,46,52],
"panels":[
{"letter":"a","role":"schematic","row":0,"col":0,"colspan":12, "chart_family":"schematic overview", "message":"…", "data_path":null, "ask":"…"},
{"letter":"b","role":"primary", "row":1,"col":0,"colspan":7, "chart_family":"scatter + trend", "message":"…", "data_path":"results.csv", "ask":"…"},
…]}
```
Outline rules (figure-style §7.1):
- **a is the hook** — schematic/hero, full width, assumes zero reader context.
- **b carries the claim** — the chart that alone makes the sentence true.
- Remaining panels are evidence, ordered by how much they strengthen b.
- One row per sub-claim. 5–10 panels for a main-text figure. Use a 12-column
grid for flexible colspans.
## 2. Render the panels (one at a time, or parallel)
Build each panel's maker prompt with `panel_task(outline, letter, fig_label)`
(kernel.py). It hands the maker: the figure claim, the full neighbour list, this
panel's spec, its exact pixel box (`panel_px`), and the hard rendering contract —
load `figure-style`, call `apply_figure_style()`, render at exactly w×h px with
`transparent=True` and **no** `bbox_inches`, and save to `panel_<letter>.png`.
**Do this yourself, one panel at a time.** Follow the `panel_task` prompt for
panel `a`, save `panel_a.png`; then `b`, and so on. The skill is designed to work
single-agent — there is no fan-out requirement, just a sequence of panels you
render against `figure-style`, each writing its own PNG:
```python
tasks = {p["letter"]: panel_task(outline, p["letter"], fig_label="Figure 2")
for p in outline["panels"]}
# For each letter, follow tasks[L] and save panel_<L>.png, then:
panel_paths = {p["letter"]: f"panel_{p['letter']}.png" for p in outline["panels"]}
```
**Parallelize only if your platform has a sub-agent tool.** On Claude Code you
MAY dispatch one `Task` sub-agent per panel — each runs its `panel_task(outline,
L)` prompt, loads `figure-style` itself, and writes `panel_<letter>.png` — then
you collect the files. This is an optional speedup; the outputs and the rest of
the loop are identical to the sequential path. Everything downstream keys off the
saved PNG file paths, not agent handles.
## 3. Compose
`compose_figure(outline, {letter: path}, out_path, letter_case=...)` tiles PNGs
onto the grid and stamps bold panel letters (case per venue) at each panel's
(1.5mm, 1mm) corner.
## 3.5 Look before you review (vision self-QA)
The §4 review pass costs you a full regeneration cycle; a panel-letter stamped
over a y-axis label or a leader line crossing a neighbour's title is a wasted
round. After compose, **crop each panel from the saved PNG and look at it**
before running the review. `compose_crops` returns PIL crop boxes; crop them to
files and open each with your agent's image tool:
```python
from PIL import Image
out_path, (W, H) = compose_figure(outline, panel_paths, "fig.png")
comp = Image.open("fig.png")
for L, box inHeadless browser automation CLI optimized for AI agents with accessibility tree snapshots and ref-based element selection
万悟平台 SSE 子会话递归嵌套与三明治序列渲染架构指南。涵盖 parentId 领养、order 绝对排序、动静 Chunk 分层及 Vue 2 响应式引用协议。
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
>
全局归档协议。只要任务需要写入任何文件(含 PLAN.md、报告、JSON 等归档物),必须按本技能执行 Session→ARCHIVE_ID、TIMESTAMP、双轨路径(根段须为 archives/)、回读校验与状态回执;WebUI 的 archive_grid 必须用 Markdown 中语言标识为 json 的围栏代码块输出。
>-
指导业务知识网络(BKN)建模,输出符合 BKN 2.0.0 的对象类型、关系类型、操作类型、风险类型与概念分组定义。适用于用户提出本体设计、知识网络建模、实体关系梳理、Action 设计、Schema 评审、从文档提取初稿或扩展现有 BKN 的场景。
>