Skip to content
Research
Skill

/figure-style

Correctness and legibility checklist for publication figures, plus a matplotlib sidecar. Load before plotting anything and call `apply_figure_style()` (role-mapped font ladder, outward ticks, frameless legends, 300-dpi saves, CJK-safe fonts). Covers data fidelity, label budgets,

BOOST
From plugin
wisp-science
1k27 skills
Install
$ npx -y skills add xuzhougeng/wisp-science --skill figure-style --agent claude-code

How 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/figure-style

Context preview

The summary Claude sees to decide when to auto-load this skill.

Correctness and legibility checklist for publication figures, plus a matplotlib sidecar. Load before plotting anything and call `apply_figure_style()` (role-mapped font ladder, outward ticks, frameless legends, 300-dpi saves, CJK-safe fonts). Covers data fidelity, label budgets,

SKILL.md

figure-style.SKILL.md
name: figure-style
description: "Correctness and legibility checklist for publication figures, plus a matplotlib sidecar. Load before plotting anything and call `apply_figure_style()` (role-mapped font ladder, outward ticks, frameless legends, 300-dpi saves, CJK-safe fonts). Covers data fidelity, label budgets, axis/colour/type rules, chart choice by data shape, composition, and a mandatory render-then-inspect QA pass (bbox collisions + per-panel visual crops). Helpers: focal_palette, bar_with_points, strip_with_median, end_of_line_labels, panel_letter, set_frame, panel_crops, save_panel_crops (QA crops go to .cache/, never into the output figures directory). Multi-panel assembly lives in figure-composer; whole-paper figure ordering in paper-narrative."
license: Apache-2.0

Figure correctness checklist

This skill makes one plot trustworthy and readable. It deliberately has no house aesthetic — frame, font family, and sizes are all parameters of `apply_figure_style()`, which must run before the first plotting call. Multi-panel assembly is `figure-composer`'s job; deciding what each figure in a paper should argue is `paper-narrative`'s.

Loading the Python helpers only defines them; it does not select a matplotlib backend or apply a style. Call `apply_figure_style(...)` explicitly for plotting. The optional `figure_style_self_check()` applies the defaults and checks font wiring when called; it is not a load-time check.

Two tiers of rule live below. **Hard rules** — everything under *Tell the truth*, *Never do*, and *Prove the render*, plus any rule stating a perceptual or factual invariant (semantic-zero centring, colour-vision safety, leader-line anchoring) — apply to every plot with no override. Everything else is a default: deviate when you have a deliberate reason, not by accident.

Tell the truth about the data

  • **Excluded means excluded.** A row the source data marks excluded either

disappears from the plot or appears as a clearly distinct open/hatched marker named in the key — and it never contaminates a summary statistic drawn next to included rows.

  • **Peers must be comparable.** Arms measured under different N, budget,

initialisation, or protocol don't sit side by side as if equivalent. Facet them apart or mark the label, and state the difference once in the caption.

  • **The figure can't contradict itself.** Before saving, trace every

categorical label, threshold, and title back to the rule that defines it and check each plotted row satisfies it. A row that contradicts its label means the figure is wrong.

  • **A sentence-title is a claim — test it.** Check the claim against every

category on the axis. One counterexample means qualifying ("on 3 of 4 pairs") or demoting the title to a description.

  • **State n and what's held fixed.** Any summary mark comes with `n` and the

unit of replication; any small-multiple that fixes a variable names the fixed value — in-panel, or in the caption when the label budget is tight.

  • **Context structure comes from references.** A tree, ordering, or topology

drawn as background (scale bar, category strip) uses an established reference. Infer it from the plotted data only when the structure is itself the finding.

  • **One claim, one number.** Each quantitative claim (accuracy, runtime,

count) has a single canonical value reused identically in every panel, caption, and the abstract — with a definition of what it measures.

Say less, and say it in the right place

The panel shows the pattern; the caption carries the context. Design for a general scientific reader, not for yourself.

  • **Floor.** Every visually distinct mark must be identifiable from the

figure alone. Deleting a label may only ever leave the reader asking "why is that there?" — never "what is that?". Comparators are named for what they are ("no joint training", "prior method"), not a role word ("baseline"). Gloss any term a general scientist can't parse.

  • **Ceiling.** Per panel: title, axis labels, ticks, series identity

(labelled once per row of small multiples), and at most 2–3 narrative annotations. More than ~6 strings beyond axes/ticks means over budget. Identity labels are floor, not budget.

  • **Caption material:** n=, held-fixed values, abbreviation expansions,

exclusion rationale, non-comparability footnotes, methods caveats.

  • **Titles state takeaways.** "Robust to gene dropout" works; "Fewer genes"

doesn't — read it aloud and if a listener would ask "fewer genes *what*?", rewrite. A row of small multiples varying one thing gets one row header, not per-panel titles.

  • **Numbers on marks: headline only.** Print the one value a reader would

quote; the axis serves the rest.

  • **Tie-break: delete and re-read.** If the message survives without the

label, the label stays gone.

Axes and scales

  • Limits clear the data by at least a marker radius on every side —

`ax.margins(0.04)` — and no mark or text touches a spine.

  • Data using under 40% of an axis calls for a break or a data-floor start

with an explicit non-zero tick. Nothing may be drawn inside a break gap: the gap has no coordinates.

  • Log ticks read as `10²`/`1k/10k/100k`, never raw exponents. Filled bars on

a log value axis are banned outright — bar length would encode the ratio to an arbitrary floor. Points with a median tick replace them.

  • In a row/column of small multiples, tick *labels* appear once (leftmost or

bottommost); interior panels keep tick marks only. Panels sharing y and differing only in x abut (`wspace≤0.06`) under one row header.

  • A panel's data envelope fills ≥75% of its rectangle; dead bands mean

reshaping the grid, not padding the panel.

  • When better-is-up/down isn't obvious from the axis label, put an upright

"higher = better" cue in the margin — once per row, never per panel, never caption-only, and never rotated with rotated text (`goodness_arrow`).

  • The full-width figure must fit the venue's doub
Read more
Ships withwisp-science

The open-source, local-first AI research workbench. WISP — Workspace for Intelligent Scientific Practice Search the literature, run Python and R, query ~80 scientific databases, and keep the trail — figures, runs, decisions, and drafts — in one project.

Get the whole plugin
Stats
1,042
Stars
106
Forks
Active
Maintenance
Rust
Language
AGPL-3.0
License
33m ago
Last commit
3mo ago
Created
5h ago
Added

Repo: xuzhougeng/wisp-science

Other skills on wisp-science.