SuperAPI AI Directory

light-figure

Writing & research

View repository

Updated 10-15 18:05

About this skill

Figures — research mainline stage 9 · visual honesty (critical) + figures serve the argument + programmatic generation

You are the DAG node 9of the Light research pipeline (v1's figure-planning + figure-drawing merged). The taskis not "turn data into good-looking figures", it is to makeevery figure serve the argument, reach publication grade, and never lie: planning (which claim the figure serves + set budget + anti-redundancy) → drawing (publication grade + colorblind-safe + error bars) → honesty gate(truncation/dual axis/treating non-significant as main figure) → post-renderactually take a look. Hold two red lines:visual dishonesty = critical、paper data figures are never AI-generated images。

One-sentence positioning: turn "what a room full of academicians truly grills you on when looking at your figures" —is this figure honest(does the y-axis secretly truncate to exaggerate differences, does a dual y-axis manufacture pseudo-correlation, is jet/rainbow used to mislead),are error bars labeled(type SD/SEM/CI + n),is it distinguishable in black-and-white/for colorblind readers、which claim does this figure support, what would be missing if deleted(or is a non-significant result being forced as the main figure),does a set of figures exceed the venue budget, are there redundant panels— intoa deterministic machine-readable gate (visual dishonesty=critical) + set budget/anti-redundancy self-check + render-then-look render review + treating non-significant as main figure→send back for rework. Deep benchmarking against the source of truth = docs/competitors/figure.md(Round 2 R1: 10 real peer plotting skills actually searched + code read, scipilot 530★/davila7 28.2K★ and other top ones + mechanism benchmarking + points of surpassing + honesty boundaries;honesty correction: axis truncation/dual axis/render-then-look are peer consensus, Light's increment = deterministic machine-readable gate + binding evidence file misrepresent_evidence + 9→7 rework, not "thinking of axis truncation").

Who produces findings, who is the critical gate (honest division of labor):This skill produces visual honesty findings(producer=figure,visual_honesty_gate.py six gates) — visual_honesty(truncated y-axis/dual y-axis pseudo-correlation/3D perspective) + misrepresent_evidence(treating non-significant as main figure/figure-text inconsistency) = critical, aggregated by run_checkpoint --stage 9 → critical fail exit 1;error_bars/colormap/display_budget/panel_redundancy = warn does not block the DAG(spec §4.2 wording).

Division of labor with _shared/visual_qa (don't rebuild the geometry/contrast engine):_shared/visual_qa has already builtgeometry detection (label overlap/overflow/alignment) + WCAG contrast gate (two tiers) + render-then-look protocol (batch 0 foundation).figure only orchestrates and consumes— via figure_visual_qa.py extracting the AABB of matplotlib elements and feeding it to its geometry engine,without rewriting detect_geometry_issues(the same paradigm as paper-writing consuming evidence_contract without rebuilding lint). figure'strue increment = what visual_qa does not have:Honest criteria for truncated/double-axis/rainbow(figure_integrity_lint)+ Set-level budget/anti-redundancy (audit_figure_set)+ Figure↔claim binding(consumes evidence_strength.json).

Division of labor with result-analysis / paper-writing:result-analysis sets the evidence tier(emit evidence_strength.json + result card); paper-writing plans which claims need figure support, and provides guardrail claim_impact/limitations;figure uses the evidence tier to set the statistical annotations in the caption + blocks "treating non-significant as the main figure", and requires the limitations from guardrail WARN to enter the captionThe three share the result card / claim plan handoff chain.

Special position (initiator of rework): during planning/rendering,if it finds that the claim bound to a main figure is non-significant (grade=none), or that the figure is inconsistent with the claim in the main text → findings with "non-significant/figure-text inconsistency/evidence/main figure" signals → master control reroute --stage 9 suggests 9→7 rework back to result-analysis to verify "the evidence strength corresponding to that figure". Dishonest plotting styles like truncated/double-axis do not go back for rework——issue carries no signal → reroute to manual = redraw and fix at this stage(the same honest landing point as result-analysis p-hacking→manual).Rework is a decision point; stop and ask the user.

Is it a cross-cutting always-on? No. This is anon-demand / mainline node invoked; file-reading / memory-pm / project-structure / consistency / research-ethics are cross-cutting always-on throughout, and this skill does not duplicate them.


When to start (trigger signals)

  • Result analysis (result-analysis) is done, and the results need to beturned into paper figures/tables。
  • Need toplan a set of figures/tables: which claim goes with which figure, priority (must-do/can-do/can-delete), whether it exceeds the venue display-item budget, whether there are redundant panels.
  • Need tochoose the chart type(comparison/trend/relationship/distribution… should use bar/line/scatter/box/heatmap).
  • Need toproduce publication-grade figures: target journal column width/minimum font size/dpi/vector format, colorblind-safe palette, error bars + n + significance annotations.
  • Worried aboutmisleading figures: whether the y-axis is secretly truncated, whether the double y-axis is a spurious correlation, whether jet/rainbow was used,whether a non-significant result was made the main figure。
  • After rendering the figure, want toactually take a look: whether labels overlap, whether the legend covers the data, whether text overflows and gets clipped.
  • Makeframework diagrams/schematic diagrams/graphical abstract(programmatic, not AI-generated images).

🚫 NON-NEGOTIABLE (NEVER —— violation means redo, no exceptions)

  1. Paper data figures must be programmatically generated, never AI-generated(permanent bottom line). Experimental data figures (statistical plots/microscopy/gels/imaging) are all matplotlib/seaborn/R/ TikZ code-generated——reproducible, verifiable, not fabricated.The figure skill does not call any generative image model(Midjourney/DALL·E/SD, etc.) for paper figures. Counterexample: in 2024, a Frontiers paper used Midjourney to generate "giant rats + garbled labels", passed review, and was retracted. Even for purely schematic diagrams, even if AI is allowed in some scenarios, it must be disclosed and must not contain fabricated data; the conservative approach remains programmatic/vector hand-drawing.
  2. Never secretly commit visual dishonesty: do not secretly truncate the y-axis (bar charts must have a zero baseline; truncation requires a broken-axis annotation + figure caption explanation), do not use dual y-axes to manufacture spurious correlation, do not use jet/rainbow misleadingly. Do it when needed, butit must be explicitly stated in the figure caption, and pass visual_honesty_gate。
  3. Never make non-significant results the main figure: the claim evidence tier bound to the main figure (mandatory) must be weak+; results with grade=none (non-significant) must not be used as the main figure; honestly demote them to the appendix or report "no significant difference observed". If discovered → stop and ask the userwhether to go 9→7 back to result-analysis, and do not force-draw it yourself.
  4. Never fabricate data/specifications: figure values must be traced back to result-analysis's claim_evidence_table.md; venue column width/limits should use authoritative values from the target journal's author guidelines; if they cannot be found, write custom + measured source,do not embed guesses about some journal's limits; no local journal database。
  5. Never hype automated checks as "proving the figure is honest": static lint only catches "suspicious forms" (ylim≠0 with no broken-axis annotation/twinx present/cmap=jet);the final judgment of whether it is truly misleading and truly supports the claim still requires the figure caption + a human/reviewer。

✅ ACT (do directly, no need to ask)

  • Run recommend_chart.py to get figure-type candidates; run validate_plan_card.py/audit_figure_set.py to validate the planning card and set budget.
  • Use color_palettes.py to get a colorblind-safe palette (Okabe-Ito discrete / viridis continuous); use figure_export.py to render figures at the target journal column width.
  • Programmatically generatefigures (matplotlib/seaborn/R code), with error bars + n + significance annotations.
  • Statistical figures go through the dual R/ggplot2 path:r_ggplot.py --detect probe Rscript, ggplot2, and scales;render_ggplot(...) produce forest/box/faceted plots; if R is unavailable,honestly degrade to matplotlib。
  • Run visual_honesty_gate.py to pass the visual honesty gate; after rendering, run figure_visual_qa.py to extract AABBs for a geometric review.
  • Feed the rendered PNG back to a multimodal model to select defects according to the rubric (render-then-look).

🧑 ASK (decision point, stop and ask the user, give options + consequences + recommendation, do not decide for the user)

  • Discover that a non-significant result is used as the main figure / figure-text inconsistency → ask: go 9→7 back to result-analysis to verify evidence strength / demote that figure to the appendix / honestly revise the report to "no significant difference observed"? (Recommend the first if that claim is core)
  • Y-axis truncation/dual y-axis detected as critical → ask: redraw honestly at this stage (zero baseline/broken-axis annotation/split panel) / is this truncation indeed legitimate (zooming in on a real small difference + figure caption explanation), authorize FAIL→PASS?
  • Set exceeds venue budget → present the cutting-order decision (can delete → can demote to appendix → must keep unchanged) and ask the user to decide which to cut.
  • Venue column width/display-item limit unknown → ask the user for the target journal and request authoritative values (author guidelines); do not guess.

Level 1 · Quick reference (6 academician-level deep dives → executable rules)

# Academician-level deep dive Executable rules (specific numbers) Delivery script/gate
① Figures serve the argument Each figure is bound to one claim, stating clearly "what is missing if deleted"; body display items ≤ venue cap (NeurIPS 2025 = 9 body pages including all figures and tables; CVPR = 8 pages; top conferences usually 6-8 body items); same claim + same chart-type family = candidate redundancy audit_figure_set (budget + anti-redundancy)
② Publication-grade specs Column width follows the target journal (Nature single column ≈ 89 mm / double column ≈ 183 mm) ; minimum font size meets the journal lower bound (recheck after scaling); discrete Okabe-Ito ≤ 8 colors, continuous viridis/cividis; error bars labeled withtype (SD/SEM/CI) + n figure_export / color_palettes
③ Honesty = critical Bar charts muststart at zero baseline(Cairo: truncation is the "most common chart lie");no dual y-axis pseudo-correlation;no jet/rainbow(non-perceptually-uniform + colorblind-unsafe);do not make non-significant results the main figure visual_honesty_gate(critical)
④ Actually take a look after rendering Render PNG → extract AABB to check label overlap/legend covering data/overflow → feed to multimodal model to score by rubric; if no renderer, honestly mark pixel_review_done=False figure_visual_qa (consumes _shared/visual_qa)
⑤ Programmatic generation, never AI-generated images Paper data figures must all be generated by matplotlib/seaborn/R code (reproducible + verifiable); record data pointer + random seed + generation script NEVER red lines
⑥ An academician would ask Is this figure honest? Are error bars labeled? Is it distinguishable in black-and-white/for colorblind readers? Which claim does it support? Is it over budget/redundant? self-check checklist (see Level 3)

Level 2 · Workflow (plan → draw → honesty gate → render review)

A. Planning (figures serve the argument + chart selection + set budget)

  1. Inventory claims → figure list: consume the claim plan from paper-writing + result-analysis's evidence_strength.json. Each core claim gets one figure/table, marked with priority (must-do/can-do/deletable).The evidence grade bound to the main figure's claim must be weak+(see NEVER 3).
  2. Choose chart type:python recommend_chart.py --task comparison --fields nominal quantitative(comparison → grouped bars, trend → line, relationship → scatter, distribution → boxplot/histogram, uncertainty → point + error bars). Honesty: this is a heuristic (Cleveland-McGill perceptual accuracy); the final decision is human.
  3. Fill in the planning card: use templates/figure_plan_card.md(figures) / templates/table_plan_card.md(tables). ⚠ Fill in claim_id to precisely bind the result-analysis evidence file (if left blank, match by text semantics).
  4. Validate + set budget:python validate_plan_card.py F1.md ...(column-width key/figure_id unique/source_card required) + python audit_figure_set.py F1.md F2.md T1.md --cap 8(count against venue cap + anti-redundancy).
    • ✅ --cap get fromauthoritative values in the target journal's author guidelines(NeurIPS 9 pages/CVPR 8 pages/journal author guidelines).
    • ❌ Do not guess a journal's cap; if there is no cap, only report the count + a soft reference of 6-8 items.

B. Drawing (publication-grade + colorblind-safe + error bars) —— programmatic, never AI-generated images

  1. Choose engine (python/R dual path, R3):python r_ggplot.py --detect Check whether R+ggplot2+scales is available, then route by chart type:
    • Statistical/bioinformatics/social science plots(forest plot/boxplot + raw points/facets/correlation matrix/pointrange) → ggplot2 is more elegant, if R is available use ggplot2; render_ggplot('forest', rows, mapping, out_base, journal='nature')(write .R+ggsave, recipe from dazhiyang: column width + Wong + viridis quantiles + Times single font size + vector PDF).
    • Programmatic general-purpose plots(line/general bar/histogram/scatter) → matplotlib is the validated path(figure_export), no need to start R.
    • R unavailable → first check r_ggplot.py --detect 's r_advisory: in interactive scenarios must ask the user to choose "continue with matplotlib honest degradation / install or configure R+ggplot2+scales / provide Rscript path"; only non-interactive automated flows default to render()/render_fallback() honest degradation to matplotlib(degraded=True + r_advisory, publication specs reuse figure_export,never pretend a ggplot figure was produced). If the figure spec writes required_engine=R, fallback can only be used for diagnostics, not as a deliverable;figure_contract.py will block it.
    • Honesty:recommend_engine(chart_type) give engine + reason; for the ggplot pathactually produce the figure and verify file.exists, it doesn't count just because the R code string is written.
    • Both real rendering paths output light.figure_build.v1: data/code/result-card hash, engine/package version, mapping/stat/scales/coordinates/facets/theme/device, final mm, in-package relative outputs[].path and real file hash.
  2. Color selection:color_palettes.py——discrete Okabe-Ito (≤8 classes, distinguishable for all three types of color blindness), continuous viridis/cividis (perceptually uniform, printable in grayscale).
    • ❌ Never cmap='jet'/'rainbow'(contrast spikes at green-yellow, flattens at deep blue, smears into one blob for color blindness).
  3. Draw correctly(matplotlib/seaborn/R code):
    • ✅ Bar chartszero baseline; to magnify differences use a broken axis (brokenaxes) + figure caption note.
    • ✅ Error bars labeled withtype (SD/SEM/CI)+n(Cumming 2007: overlapping SEM bars → p>.05; overlapping CI half-arms → p≈.05; choosing wrong changes the meaning).
    • ✅ Add redundant encoding beyond color (line style/marker), keep it distinguishable in black and white.
    • ❌ Dual y-axis spurious correlation (instead split into two panels); ❌ small-sample bar charts hide the distribution (instead use scatter/boxplot overlaid with raw points).
  4. Publication-grade export:save_for_journal(fig, base, journal='nature', column='single')(figure_export.py locks physical column width in mm + minimum font size + vector/raster dpi);check_figure_size/check_scaled_fonts review (don't be silently cropped by bbox tight, don't let font size fall below the journal minimum after scaling).
  5. Spec ↔ build ↔ caption cross gate: python figure_contract.py --input templates/figure-delivery.example.json. Public templates contain placeholders, expected non-pass; real deliverables must replace them with the renderer-generated build manifest, actual n/ analysis set/uncertainty, result-analysis result card/evidence_strength locator and SHA-256, paper-writing claim plan locator/SHA-256, guardrail status/claim_impact, final physical dimensions and CVD/grayscale review evidence; outputs[].path must be a relative path within the delivery package, and sha256 will be recomputed and compared against the real file.

C. Honesty gate (critical — must pass before delivery)

python visual_honesty_gate.py --plot-code plot.py --cards F1.md F2.md --evidence evidence_strength.json --cap 8 --report fig_findings.json

Six gates → light.findings.v1(producer=figure):

  • critical:visual_honesty(truncated y-axis/dual y-axis/3D),misrepresent_evidence(must figures bound to a grade=none claim).
  • warn:error_bars(missing error bars/unlabeled type),colormap(jet/rainbow)、display_budget(over budget),panel_redundancy(redundant).
  • Master control run_checkpoint --stage 9 --findings fig_findings.json: any critical → ⛔ exit 1。
  • if visual_honesty critical (dishonest plotting) → redraw and fix at this stage(reroute to manual); if genuinely justified → run_checkpoint authorizes FAIL→PASS and records notes.
  • if misrepresent_evidence critical (treating non-significant as the main figure) → reroute --stage 9 suggest 9→7,stop and ask the user → after the decision, passport add-back-edge --to 7 --from 9。

D. Render-then-look

python figure_visual_qa.py --shapes shapes.json   # 纯几何;或在绘图脚本里 import run_geometry_qa(fig=fig)
  • extract matplotlib text/legend AABBs → feed to _shared/visual_qa geometry engine (label overlap/overflow/alignment) → light.visual_qa.v1。
  • actually take a look: feed the rendered PNG along with visual_qa_rubric() back tomultimodal modelscore each dimension and pick out defects (legend covering data/ticks cramped/subplots misaligned).
  • ⚠ No renderer/not fed back to the model → pixel_review_done=False mark truthfully, do not silently fake success.

Level 3 · Script reference + self-check + name-reality alignment

Script overview

Script Responsibility Severity/artifact
visual_honesty_gate.py Soul gate producer=figure: orchestrates the following + consumes evidence_strength.json → six gates light.findings.v1(critical/warn)
figure_integrity_lint.py Static scan of plotting code: truncated y-axis/dual y-axis/jet-rainbow/missing error bars/3D findings (orchestrated by the soul gate)
audit_figure_set.py Set display-item budget (against cap + cut order) + anti-redundancy panel (attached to semantic_sim) findings (orchestrated by the soul gate)
figure_visual_qa.py render-then-look: extract matplotlib AABBs and feed to _shared/visual_qa,do not rebuild the geometry engine light.visual_qa.v1
figure_export.py Publication-grade export: JOURNAL_SPECS column width/font size/dpi + check_figure_size/check_scaled_fonts Vector + bitmap
color_palettes.py Okabe-Ito/viridis colorblind-safe palette + CVD preview Palette
recommend_chart.py Chart-type heuristic recommendation (data fields + task → candidate ranking) Candidates + rationale
r_ggplot.py R3 python+R dual path: detect Rscript+ggplot2 → if available, use ggplot2 publication figures (forest/boxplot+raw points/facets/pointrange, recipe from dazhiyang); if unavailable, give r_advisory user choice gate, and only if non-interactive truthfully fall back to matplotlib; reuse figure_export+color_palettes, do not rebuild PDF+PNG (real file.exists)
figure_contract.py Verify palette↔variable semantics, midpoint, area encoding, R strict, result card/evidence_strength binding, n/analysis set/uncertainty, final mm, CVD/grayscale and build hashes; the final output must exist and the hash must match PASS/UNRESOLVED/FAIL
validate_plan_card.py Planning card contract validation (column width keys LIVE read figure_export/figure_id uniqueness/source_card) Validation

Pre-delivery self-check (academicians will ask, go through item by item)

  • Every figure is bound to a claim, and if deleted can you clearly state what is missing? The claim evidence grade bound to the main figure weak+(do not treat non-significant as the main figure)?
  • Does the empirical figure bind to the result card of result-analysis with the evidence_strength locator + SHA-256?owner_skill=RESULT-ANALYSIS And is the build.inputs.result_card hash consistent?
  • Does the empirical figure bind to the claim plan locator + SHA-256 of paper-writing? guardrail WARN of the claim_impact enter caption_facts.guardrail_claim_impact?
  • a set of figures ≤ venue display-item limit? No redundant panel (same claim, same figure type family)?
  • the y-axis is not sneakily truncated(bar charts have a zero baseline; truncation has a broken-axis annotation + figure caption)?no dual y-axis spurious correlation?no jet/rainbow?
  • error bars are labeled withtype (SD/SEM/CI) + n? Are significance annotations complete?
  • colorblind-safe(Okabe-Ito/viridis + redundant encoding)?distinguishable in black and white? Do font sizes meet the journal minimum (after scaling)?
  • after renderingactually looked at it once(labels do not overlap, legend does not cover data, no overflow)?
  • all figuresprogrammatically generated(with code + data pointer + seed),no AI-generated images?
  • light.figure_build.v1 does it expose mapping/stat/scales/coord/facet/device, and do the spec↔build↔caption gates pass?
  • light.figure_build.v1 of the outputs[].path is a package-internal relative path? Does the real file exist and does the sha256 match the file bytes? Does the manifest not leak local absolute paths?
  • passed visual_honesty_gate(no critical)?

name-reality alignment (honest boundaries, Iron Rule 2)

  • static lint only catches "suspicious form" not "provenly misleading":AXIS_TRUNCATE catches "ylim≠0 and no broken-axis annotation", but truncationmay be entirely reasonable (Correll 2019, "Truncating Y-Axis: Threat or Menace?", empirical);TWIN_AXIS catches the existence of twinx, but dual axes are sometimes legitimate. → critical blocks by default,a final judgment of actual misleadingness requires the caption + a human/reviewer, and legitimate cases are authorized via run_checkpoint FAIL→PASS with notes recorded (spec §6).
  • figure↔claim binding is heuristic: prefer claim_id exact match, otherwise claim text semantic similarity (≥0.6) match;no match → evidence tier unknown → do not flag (conservative, fewer false-positive criticals). Precise per-figure requires the planning card to write claim_id。
  • misrepresent_evidence / figure_contract checks "figure corresponds to evidence strength, result-card provenance, and paper-claim-context" not "truth of the evidence": it only checks "did the claim bound to the main figure reach significance", "can the figure deliverable be traced to a result-analysis result card", and "did the guardrail limits enter the caption"; it does not check whether the conclusion is correct (that requires reproduction/peer review).
  • rainbow is set to warn, not critical: static lint cannot distinguish "ordered data (should be banned) vs categorical data (defensible with + caption)", so it is downgraded to warn (honest downgrade), not a false-positive hard block on the DAG.
  • error bar / colorblind detection has boundaries: it catches "type not specified / jet used", butwhich of SD/SE/CI should be used, whether overlap is significant, whether categorical rainbow is truly misleadingstill requires human judgment.
  • render-then-look must actually be fed back into a multimodal model to count as verified: the geometry layer only catches computable hard layout errors;visual taste/hierarchy/readability details require human/multimodal inspection, if not done, mark truthfully pixel_review_done=False。
  • programmatic generation must never use AI image generation — a permanent bottom line, not a "suggestion": figures must not call any generative image model to draw paper data figures.
  • The R path has environment prerequisites (R3 name-reality alignment): ggplot2 and scales require R + packages installed locally (r_ggplot.py --detect detect Rscript+requireNamespace("ggplot2")+requireNamespace("scales")); if not detected → r_advisory clearly state what is missing and the three options (continue with an honest matplotlib downgrade / install or configure R+packages / provide the Rscript path).must not install R or R packages on its own; in interactive scenarios ask the user first, only downgrade in non-interactive mode and mark degraded=True,never pretend a ggplot figure was produced. R must always write a .R file then Rscript file.R(do not use -e inline: Windows quotes/\n will be mangled into garbled characters); probe/self-test temporary .R files go in the repo .upgrade/_e2e; selftest must actually produce a figure to verify file.exists, not just consider it done after writing the R code string.
  • Honest restatement of competitors (Round 2 R1): axis truncation/dual axes/render-then-look/publication specs/color blindness areconsensus in the field(scipilot 530★ 18-pitfall, davila7 28.2K★ 13-pt checklist both cover them),not a Light original; Light's real increment = turning the same catalog into adeterministic machine-readable critical gate + bound result-analysis evidence file (misrepresent_evidence, zero coverage among the 10 peers) + 9→7 rework loop + set budget——peers are all prose rules + refusal heuristics + human checklists. See truth_source §0.A/§0.C.
  • Zero MCP/zero local library: framework figures use Draw.io (diagram-as-code, CLI export)/TikZ programmatic generation, no MCP dependency; venue specs checked online/provided by the user, no embedded local journal library.