figure-design — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited figure-design (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Guide the creation of a research figure with the same discipline Eureka applies to everything else: gates before rendering, iron laws that do not bend, a hard prohibition on chart junk, and a fresh-eyes subagent review after every figure. A figure is an argument — every pixel either advances it or distracts from it.
Core principle: A peer reviewer spends 3 seconds on a figure before forming an opinion. Those 3 seconds decide whether they read the caption, the text, or the paper at all.
NO FIGURE WITHOUT A GENERATING SCRIPT.
NO SUBMISSION WITHOUT COLORBLIND-SAFE PALETTE.
NO DEFAULT MATPLOTLIB STYLE IN A TOP-JOURNAL SUBMISSION.Writing a figure means writing a script that produces it deterministically. Picking a palette means picking one that 8% of male readers can still decode. Setting a style means setting it once at the top of the script and never editing the output manually.
Use this skill when:
Do NOT use when:
eureka:claims-audit Part B)eureka:manuscript-writing)You MUST create a task for each of these and complete them in order:
CLAUDE.md / the manuscript. Different journals have different column widths, fonts, formats.apply_paper_style()-equivalent at the top of the script (font family, TrueType embedding, DPI, spine style).py/.R and the .pdf/.svg go to git<HARD-GATE> Before writing any plotting code, state the figure's purpose in one sentence and select the chart type from this table. If your purpose doesn't match any row, stop and ask the user to clarify. </HARD-GATE>
| Purpose | First choice | Acceptable alternative | Avoid |
|---|---|---|---|
| Compare ≤5 groups on one metric | Horizontal bar chart | Grouped vertical bar | Pie chart, 3D bar |
| Compare >5 groups on one metric | Dot plot, lollipop chart | Heatmap (if >10) | Stacked bar, spaghetti line |
| Show distribution of a single variable | Violin plot, histogram | Box plot with raw points overlaid | Bar of mean only (hides spread) |
| Show distribution across groups | Violin + strip, raincloud plot | Box + swarm | Bar chart of means |
| Show trend over time (continuous) | Line plot with CI band | Scatter + LOESS | Bar chart with time on x-axis |
| Show relationship between 2 continuous variables | Scatter + regression line | Hexbin (if N is large) | 3D scatter |
| Show rank ordering | Dot plot, horizontal bar | Slope chart (if 2 timepoints) | Pie chart |
| Part-to-whole (few categories, one total) | Stacked horizontal bar | Tree map | Pie chart with >3 slices, donut chart |
| Show flow / transition | Sankey diagram, alluvial plot | Chord diagram | Network diagram with arbitrary arrows |
| Show spatial pattern (brain, map, chip) | Heatmap on native coordinates | Glass-brain projection (neuroscience) | Volume rendering for 2D questions |
| Show matrix of pairwise relationships | Heatmap with clustering | Correlation matrix with dendrogram | Separate scatter plots per pair |
| Show two metrics simultaneously | Scatter with size encoding | Dual-axis line (only if scales compatible) | Dual-axis with unrelated scales |
Anti-patterns (never use these):
These apply regardless of tool, field, or journal:
plt.rcParams['pdf.fonttype'] = 42 and plt.rcParams['ps.fonttype'] = 42. Default Type 3 fonts are rejected by most journals.tab10. All colorblind-safe.viridis, cividis, plasma, inferno. All perceptually uniform and colorblind-safe.RdBu_r, coolwarm, PuOr. Colorblind-safe if tested.jet for sequential data (not perceptually uniform)docs/references/figure-guide.md for copy-paste hex codes.axes.spines.top: False, axes.spines.right: False) — they add ink without informationframeon=FalseSee the Journal Export Gate below for the table.
Figure + legend alone must be interpretable without reading the main text. Reviewers often evaluate figures independently of the Methods section and the Results prose. If a reader can't understand the figure from the legend, the figure fails peer review regardless of how pretty it is.
Every figure with a statistical test, error bars, or group comparison must state in the legend:
n represents and sample independence where applicable. Examples by field: biology — "3 biological replicates (animals), 5 technical replicates each"; ML/physics — "10 independent random seeds"; psychology/HCI — "24 subjects, 40 trials each"; clinical — "50 patients, 1 scan each"p = 0.003); if using asterisks, the legend must define them (*p < 0.05, **p < 0.01, ***p < 0.001)Missing any one of these is the single most common figure-related reviewer flag at top-tier journals.
For distributions or group comparisons, show individual data points overlaid on summary statistics whenever sample size permits (violin + strip, box + jitter, raincloud, strip plot with mean line). Bar chart of mean + error whisker alone ("dynamite plot") is the #1 flagged visualization anti-pattern in top-journal review (eLife: Ten common statistical mistakes). The rule of thumb: overlay raw points when N per group ≤ 50; above that overlay becomes illegible and summary statistics are acceptable.
<HARD-GATE> Before calling savefig() (or equivalent), confirm the target journal's requirements from docs/references/figure-guide.md. If unknown, ask the user. </HARD-GATE>
Inline summary (full table in docs/references/figure-guide.md):
| Journal family | 1-col width | 2-col width | Font | Font size | DPI (raster) | Preferred format |
|---|---|---|---|---|---|---|
| Nature family | 89mm | 183mm | Arial/Helvetica | 5-7pt | 300+ | PDF/AI/EPS for vector; TIFF/PNG for raster |
| Science family | 55mm | 115/180mm | Helvetica | 6-12pt | 300+ | PDF/EPS preferred |
| Cell family | 85mm | 174mm (full); 114mm (1.5-col) | Arial/Helvetica | 6-8pt | 300+ | PDF preferred; EPS/TIFF accepted |
| JAMA / NEJM | 3.375" | 6.75" | Arial | 7-9pt | 300+ | EPS/PDF; TIFF for raster |
| IEEE Transactions | 3.5" (88.9mm) | 7.16" (182mm) | Times/Helvetica | 8pt min | 300+ | PDF/EPS |
For each figure, follow these steps in order:
"This figure shows [what] for [what purpose], to support [what claim]."
If you can't finish that sentence, you're not ready to plot. Ask the user.
Use the Chart Type Selection Gate table. Write the choice in a comment at the top of the script: # Chart type: horizontal bar (compare 5 models on r²).
At the top of the plotting script, call a style function that sets:
pdf.fonttype = 42)See docs/references/figure-guide.md for a copy-paste-ready apply_paper_style() recipe.
Write the plotting code. Use named color variables, not hex strings inline. Keep one figure per script (or one composite function per script).
Call savefig('figures/fig_name.pdf', bbox_inches='tight', pad_inches=0.02). If a raster version is needed, also save .png at 600 DPI.
Before dispatching the reviewer, run through:
n, statistical test, error bar type, and center value?figure-reviewer subagentLocate the reviewer prompt at skills/figure-design/figure-reviewer-prompt.md. Fill the placeholders:
{FIGURE_PATH} — path to the output file (e.g., figures/fig3.pdf){SCRIPT_PATH} — path to the generating script{FIGURE_PURPOSE} — one-sentence purpose from Step 1{TARGET_JOURNAL} — e.g., "Nature Communications"{CAPTION_TEXT} — the draft caption (if written), else "N/A"Dispatch via Task tool (general-purpose subagent). Wait for Status: Approved or Status: Issues Found.
manuscript-writingIf the reviewer flags the same issue twice, escalate to the user.
Both the script (.py/.R/.jl) AND the output file (.pdf/.svg) go to git. The output file is a build artifact, but committing it protects against environment drift — the paper reader can see what the authors saw even if their TeX/matplotlib environment differs.
| Excuse | Reality |
|---|---|
| "Default matplotlib style is fine for now" | Default is 100 DPI, bitmap fonts, blue axis labels. Journals silently reject; reviewers assume carelessness. Set the style upfront, not later. |
| "Viridis is overused, let me pick a prettier palette" | Viridis is perceptually uniform AND colorblind-safe. Pretty is irrelevant; the reader's job is to decode, not admire. |
| "I'll fix the typography later in Illustrator" | Manual edits break reproducibility (claims-audit fails). Anyone running the script should get the submitted figure byte-for-byte. Fix in the script. |
| "Pie chart is fine, it's only 3 categories" | Horizontal bar beats pie at any N. Humans compare lengths faster and more accurately than angles. |
| "The legend fits if I shrink it" | Sub-5pt text is unreadable in print. Move the legend outside the axes, split panels, or drop it entirely — never shrink below 5pt. |
| "Red vs green is intuitive for error/success" | 8% of men see them as the same color. Use blue/orange, add shape coding, or annotate directly. |
| "The figure looks fine on my screen" | Screens are 100-200 DPI RGB. Print is 300+ DPI CMYK. Always export to PDF and inspect at 100% zoom before declaring done. |
| "Journal guidelines are for final submission — draft can be loose" | Drafts become submissions through editorial inertia. Fixing typography at submission time is 10x the cost of setting a global style once. |
| "I'll just screenshot the Jupyter notebook output" | Screenshots are raster at screen DPI, no vector, no TrueType. Always save via savefig('.pdf'). |
| "The figure has to look exactly like a specific paper's visualization" | Mimicking an exemplar is fine; copying the exact palette, colorbar, and layout is not. Derive from principles, not from a specific paper's stylistic choices. |
| "n is in Methods — don't need it in the legend" | Reviewers read figure legends independently of Methods. Put n in BOTH. |
| "Bar chart of mean is standard practice" | It is — and it's the single most-flagged visualization anti-pattern in top-journal review (eLife top-10). Show the raw points. |
| "Asterisks for p-values are fine, everyone uses them" | Only if the legend defines them. *p<0.05 alone is not enough; prefer exact values (p = 0.003). |
| "This is a representative image, obviously" | Not obvious to reviewers. Label it "representative of N independent experiments" or state the quantification N. |
jet / rainbow cmap for a sequential quantity.jpg or a screenshot-based formatn, statistical test, or error bar definitionclaims-auditfigure-design and claims-audit Part B (Figure Integrity) are orthogonal and both run:
| Concern | Owned by |
|---|---|
| Does the generating script exist? | claims-audit |
| Is the output reproducible from the script? | claims-audit |
| Are the plotted numbers traceable to a results file? | claims-audit |
| Is the chart type appropriate for the data and purpose? | figure-design |
| Is the typography readable and embedded correctly? | figure-design |
| Is the palette colorblind-safe? | figure-design |
| Does the figure match journal export specs? | figure-design |
A figure can pass one and fail the other. Both must pass for submission-readiness.
eureka:using-eureka when figure creation intent is detected; eureka:manuscript-writing when Results section cites a figurefigure-reviewer subagent (per figure, after rendering)eureka:claims-audit (integrity) — orthogonal, both run before submissiondocs/references/figure-guide.md (for journal-specific specs, palette hex codes, matplotlib style recipe, accessibility tools, chart-type flowchart)FLEXIBLE — Chart type, palette choice, and journal target adapt to the user's field, data, and venue. The iron laws (colorblind-safe palette, 5pt font floor, TrueType embedding, no chart junk, vector export, script-generated only) are fixed.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.