Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Generate publication-quality figures and tables from experiment results. Use when user says "画图", "作图", "generate figures", "paper figures", or needs plots for a paper.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 204% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 49% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 121% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 111% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 132% | 0% |
Generate all figures and tables for a paper based on: $ARGUMENTS
| Category | Can auto-generate? | Examples | |----------|-------------------|----------| | Data-driven plots | ✅ Yes | Line plots (training curves), bar charts (method comparison), scatter plots, heatmaps, box/violin plots | | Comparison tables | ✅ Yes | LaTeX tables comparing prior bounds, method features, ablation results | | Multi-panel figures | ✅ Yes | Subfigure grids combining multiple plots (e.g., 3×3 dataset × method) | | Architecture/pipeline diagrams | ❌ No — manual | Model architecture, data flow diagrams, system overviews. At best can generate a rough TikZ skeleton, but expect to draw these yourself using tools like draw.io, Figma, or TikZ | | Generated image grids | ❌ No — manual | Grids of generated samples (e.g., GAN/diffusion outputs). These come from running your model, not from this skill | | Photographs / screenshots | ❌ No — manual | Real-world images, UI screenshots, qualitative examples |
In practice: For a typical ML paper, this skill handles ~60% of figures (all data plots + tables). The remaining ~40% (hero figure, architecture diagram, qualitative results) need to be created manually and placed in figures/ before running /paper-write. The skill will detect these as "existing figures" and preserve them.
publication — Visual style preset. Options: publication (default, clean for print), poster (larger fonts), slide (bold colors)pdf — Output format. Options: pdf (vector, best for LaTeX), png (raster fallback)tab10 — Default matplotlib color cycle. Options: tab10, Set2, colorblind (deuteranopia-safe)figures/ — Output directory for generated figuresgpt-5.6-sol — Model used via a secondary Codex agent for figure quality review./paper-plan)figures/ or project rootIf no PAPER_PLAN.md exists, scan for data files and ask the user which figures to generate.
Parse the Figure Plan table from PAPER_PLAN.md:
markdown| ID | Type | Description | Data Source | Priority | |----|------|-------------|-------------|----------| | Fig 1 | Architecture | ... | manual | HIGH | | Fig 2 | Line plot | ... | figures/exp.json | HIGH |
Identify:
Create a shared style configuration script:
python# paper_plot_style.py — shared across all figure scripts import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams.update({ 'font.size': FONT_SIZE, 'font.family': 'serif', 'font.serif': ['Times New Roman', 'Times', 'DejaVu Serif'], 'axes.labelsize': FONT_SIZE, 'axes.titlesize': FONT_SIZE + 1, 'xtick.labelsize': FONT_SIZE - 1, 'ytick.labelsize': FONT_SIZE - 1, 'legend.fontsize': FONT_SIZE - 1, 'figure.dpi': DPI, 'savefig.dpi': DPI, 'savefig.bbox': 'tight', 'savefig.pad_inches': 0.05, 'axes.grid': False, 'axes.spines.top': False, 'axes.spines.right': False, 'text.usetex': False, # set True if LaTeX is available 'mathtext.fontset': 'stix', }) # Color palette COLORS = plt.cm.tab10.colors # or Set2, or colorblind-safe def save_fig(fig, name, fmt=FORMAT): """Save figure to FIG_DIR with consistent naming.""" fig.savefig(f'{FIG_DIR}/{name}.{fmt}') print(f'Saved: {FIG_DIR}/{name}.{fmt}')
Use this decision tree for data-driven figures (inspired by Imbad0202/academic-research-skills):
| Data Pattern | Recommended Type | Size | |-------------|-----------------|------| | X=time/steps, Y=metric | Line plot | 0.48\textwidth | | Methods × 1 metric | Bar chart | 0.48\textwidth | | Methods × multiple metrics | Grouped bar / radar | 0.95\textwidth | | Two continuous variables | Scatter plot | 0.48\textwidth | | Matrix / grid values | Heatmap | 0.48\textwidth | | Distribution comparison | Box/violin plot | 0.48\textwidth | | Multi-dataset results | Multi-panel (subfigure) | 0.95\textwidth | | Prior work comparison | LaTeX table | — |
For each figure in the plan, create a standalone Python script:
Line plots (training curves, scaling):
python# gen_fig2_training_curves.py from paper_plot_style import * import json with open('figures/exp_results.json') as f: data = json.load(f) fig, ax = plt.subplots(1, 1, figsize=(5, 3.5)) ax.plot(data['steps'], data['fac_loss'], label='Factorized', color=COLORS[0]) ax.plot(data['steps'], data['crf_loss'], label='CRF-LR', color=COLORS[1]) ax.set_xlabel('Training Steps') ax.set_ylabel('Cross-Entropy Loss') ax.legend(frameon=False) save_fig(fig, 'fig2_training_curves')
Bar charts (comparison, ablation):
pythonfig, ax = plt.subplots(1, 1, figsize=(5, 3)) methods = ['Baseline', 'Method A', 'Method B', 'Ours'] values = [82.3, 85.1, 86.7, 89.2] bars = ax.bar(methods, values, color=[COLORS[i] for i in range(len(methods))]) ax.set_ylabel('Accuracy (%)') # Add value labels on bars for bar, val in zip(bars, values): ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.3, f'{val:.1f}', ha='center', va='bottom', fontsize=FONT_SIZE-1) save_fig(fig, 'fig3_comparison')
Comparison tables (LaTeX, for theory papers):
latex\begin{table}[t] \centering \caption{Comparison of estimation error bounds. $n$: sample size, $D$: ambient dim, $d$: latent dim, $K$: subspaces, $n_k$: modes.} \label{tab:bounds} \begin{tabular}{lccc} \toprule Method & Rate & Depends on $D$? & Multi-modal? \\ \midrule \citet{MinimaxOkoAS23} & $n^{-s'/D}$ & Yes (curse) & No \\ \citet{ScoreMatchingdistributionrecovery} & $n^{-2/d}$ & No & No \\ \textbf{Ours} & $\sqrt{\sum n_k d_k / n}$ & No & Yes \\ \bottomrule \end{tabular} \end{table}
Architecture/pipeline diagrams (MANUAL — outside this skill's scope):
figures/, preserve it and generate only the LaTeX \includegraphics snippet[MANUAL] in the figure plan and latex_includes.texbash# Run all figure generation scripts for script in gen_fig*.py; do python "$script" done
Verify all output files exist and are non-empty. Then render-then-verify: re-open each RENDERED PDF/PNG (not the script) and self-check — no clipped labels, no legend covering data, every number/label readable at final print size. This self-check happens BEFORE the Step 7 review, so the reviewer's budget goes to substance, not to catching clipped axes.
For each figure, output the LaTeX code to include it:
latex% === Fig 2: Training Curves === \begin{figure}[t] \centering \includegraphics[width=0.48\textwidth]{figures/fig2_training_curves.pdf} \caption{Training curves comparing factorized and CRF-LR denoising.} \label{fig:training_curves} \end{figure}
Save all snippets to figures/latex_includes.tex for easy copy-paste into the paper.
Send figure descriptions and captions to GPT-5.6-Sol for review:
spawn_agent:
model: gpt-5.6-sol
reasoning_effort: xhigh
message: |
Review these figure/table plans for a [VENUE] submission.
For each figure:
1. Is the caption informative and self-contained?
2. Does the figure type match the data being shown?
3. Is the comparison fair and clear?
4. Any missing baselines or ablations?
5. Would a different visualization be more effective?
[list all figures with captions and descriptions]The checklist is PARTITIONED (pattern from Anthropic's Claude Science figure-style skill, Apache-2.0): correctness rules always bind — they are about whether the figure tells the truth, have no aesthetic content, and no style choice may override them; guidance rules are defaults — they produce a clean result, but a deliberate, stated alternative may override them.
Correctness — always binds, verify against the DATA before the render:
source either disappears entirely or is drawn visibly distinct (open / hatched marker, named in the key); it never feeds a mean/CI plotted alongside included rows
row — if one category contradicts the claim, qualify it ("on 3 of 4 benchmarks") or downgrade to a description; a figure that overclaims is wrong even if it renders beautifully
/ protocol are not drawn as visual peers; separate them or mark the difference in the caption
says n and the unit of replication (panel or caption)
(not the script) actually happened: no clipped labels, no legend covering data, every number/label readable at final print size
Guidance — strong defaults (from pedrohcgs/claude-code-my-workflow), a deliberate stated alternative may override — EXCEPT items that Key Rules below make hard (vector-PDF output and no-titles-inside-figures are Key Rules: treat those two as binding, not overridable):
\caption{} (from pedrohcgs)emp_rate)plt.title for publications)figures/
├── paper_plot_style.py # shared style config
├── gen_fig1_architecture.py # per-figure scripts
├── gen_fig2_training_curves.py
├── gen_fig3_comparison.py
├── fig1_architecture.pdf # generated figures
├── fig2_training_curves.pdf
├── fig3_comparison.pdf
├── latex_includes.tex # LaTeX snippets for all figures
└── TABLE_*.tex # standalone table LaTeX files| Type | When to Use | Typical Size | |------|------------|--------------| | Line plot | Training curves, scaling trends | 0.48\textwidth | | Bar chart | Method comparison, ablation | 0.48\textwidth | | Grouped bar | Multi-metric comparison | 0.95\textwidth | | Scatter plot | Correlation analysis | 0.48\textwidth | | Heatmap | Attention, confusion matrix | 0.48\textwidth | | Box/violin | Distribution comparison | 0.48\textwidth | | Architecture | System overview | 0.95\textwidth | | Multi-panel | Combined results (subfigures) | 0.95\textwidth | | Comparison table | Prior bounds vs. ours (theory) | full width |
Design pattern (type × style matrix) inspired by baoyu-skills. Publication style defaults and figure rules from pedrohcgs/claude-code-my-workflow. Visualization decision tree from Imbad0202/academic-research-skills.
Other measured skills in the registry, with their headline benchmark lift.