plotting-agent

$npx mdskill add Ar9av/PaperOrchestra/plotting-agent

Executes the visualization plan from outline.json to render paper figures.

  • Generates publication-quality plots from experimental logs and idea documents.
  • Uses matplotlib via Python/Bash tools and optionally a VLM for critique.
  • Follows the plotting_plan in outline.json to determine what to render.
  • Saves PNG figures and a captions.json file to the workspace.

SKILL.md

.github/skills/plotting-agentView on GitHub ↗
---
name: plotting-agent
description: Step 2 of the PaperOrchestra pipeline (arXiv:2604.05018). Execute the visualization plan from outline.json — render plots and conceptual diagrams from experimental_log.md and idea.md, optionally refine via VLM critique loop, and produce context-aware captions. Runs in parallel with the literature-review-agent. TRIGGER when the orchestrator delegates Step 2 or when the user asks to "generate the figures for my paper" or "render the plots from this experiment log".
---

# Plotting Agent (Step 2)

Faithful implementation of the Plotting Agent from PaperOrchestra
(Song et al., 2026, arXiv:2604.05018, §4 Step 2 and App. F.1 p.45).

**Cost: ~20–30 LLM calls.** The paper uses PaperBanana (Zhu et al., 2026) as
the default backbone with a closed-loop VLM-critique refinement. This skill
expresses that loop in host-agent terms: you (the host agent) generate
matplotlib code with your own LLM, render via your Bash/Python tool,
optionally critique the rendered PNG with your vision model, redraw, and
finally caption.

## Inputs

- `workspace/outline.json` — specifically the `plotting_plan` array
- `workspace/inputs/idea.md` and `workspace/inputs/experimental_log.md` —
  the source data
- `workspace/inputs/figures/` — optional pre-existing figures (`PlotOn` mode)

## Outputs

- `workspace/figures/<figure_id>.png` — one PNG per `plotting_plan` entry
  (300 DPI, sized to the requested aspect ratio)
- `workspace/figures/captions.json` — `{figure_id: caption_text}` map

## Workflow

### Per figure (executed independently per `figure_id`)

1. **Read the figure spec** from `outline.json`:
   ```json
   {
     "figure_id": "fig_main_results",
     "title": "Main Results on Dataset X",
     "plot_type": "plot",
     "data_source": "experimental_log.md",
     "objective": "Visual summary (Grouped Bar Chart) demonstrating ...",
     "aspect_ratio": "5:4"
   }
   ```

2. **Few-shot retrieval (visual planning)**: pick the matching pattern from
   `references/chart-patterns.md` (for `plot_type=="plot"`) or
   `references/diagram-patterns.md` (for `plot_type=="diagram"`).

3. **Extract data**: parse `idea.md` and/or `experimental_log.md`
   (`data_source` field tells you which) to obtain the numeric values or
   conceptual entities the figure needs. For `experimental_log.md`, the
   `## 2. Raw Numeric Data` section contains markdown tables.

4. **Render**:

   **If `PAPERBANANA_PATH` is set** — use the PaperBanana backbone
   (Zhu et al., 2026). It runs a Retriever → Planner → Stylist → Visualizer
   → Critic loop and is especially good for `plot_type == "diagram"`.
   See `references/paperbanana-cookbook.md` for setup (needs a Gemini API key).

   ```bash
   python skills/plotting-agent/scripts/paperbanana_render.py \
       --figure-id <figure_id> \
       --caption   "<objective from figure spec>" \
       --content-file workspace/inputs/idea.md \
       --task      <diagram|plot> \
       --aspect-ratio <aspect_ratio> \
       --out       workspace/figures/<figure_id>.png
   ```

   **Otherwise** — write a matplotlib script and run it via your Bash tool,
   or use the bundled helper:
   ```bash
   python skills/plotting-agent/scripts/render_matplotlib.py \
       --spec spec.json \
       --out workspace/figures/<figure_id>.png
   ```
   The script must apply the academic style from `chart-patterns.md`, use the
   correct pixel size from `aspect-ratios.md`, save at 300 DPI, and call
   `plt.close()` after `savefig`.

5. **VLM critique loop (optional, only if your host has vision)**:
   - Reload the rendered PNG as a multimodal input to your LLM.
   - Critique it against the figure's `objective` from the outline. Look for:
     visual artifacts, mislabeled axes, illegible text, color clashes,
     misleading scaling, missing legend, overlapping labels.
   - If problems are found, regenerate the matplotlib script with corrections
     and re-render. Cap at 3 critique iterations per figure.
   - This is the closed-loop refinement step the paper inherits from
     PaperBanana. See `references/plotting-pipeline.md` for the full loop
     description.
   - **If your host has no vision input, skip this step entirely.** The
     figure will still render correctly, just without iterative refinement.

6. **Generate the caption** using the verbatim Caption Generation prompt at
   `references/caption-prompt.md`. Inputs to the caption prompt:
   - `task_name` — the section the figure belongs to (e.g., "Methodology",
     "Experiments")
   - `raw_content` — the surrounding section text (or content_bullets from
     the section_plan if the section isn't drafted yet)
   - `description` — the `objective` field from the figure spec
   - `figure_desc` — a 1-sentence description of what the rendered figure
     actually shows (from your VLM critique pass, or from the script's plan
     if no vision)

   Write the caption to `workspace/figures/captions.json` keyed by
   `figure_id`. **Captions must NOT contain `Figure N:` or `Caption N:`
   prefixes** — the LaTeX template handles numbering. Plain text only, no
   markdown.

## Conceptual diagrams

For `plot_type == "diagram"`, prefer PaperBanana when available — its
Retriever grounds the Planner in real published paper diagrams.  If
`PAPERBANANA_PATH` is unset, follow `references/diagram-patterns.md`.
Patterns include block diagrams, system overviews, flowcharts, and
algorithm-as-graph. The bundled helper:

```bash
python skills/plotting-agent/scripts/render_diagram.py \
    --spec diagram_spec.json \
    --out workspace/figures/<figure_id>.png
```

handles the simple cases (boxes-and-arrows). For complex Fig-1-style
overview diagrams, write matplotlib patches code yourself.

## Hard rules

- **300 DPI** for every figure. Lower DPI gets rejected at the LaTeX compile
  step on conference templates.
- **Aspect ratio is exact**. The figure spec's `aspect_ratio` is one of 12
  enumerated strings. Use the pixel targets in `references/aspect-ratios.md`.
- **Hide top and right spines** for plots. (Diagrams: no spines at all.)
- **Muted academic colors** only. The palette is in `chart-patterns.md`.
  Never use matplotlib defaults (too saturated for print).
- **No 3D, no pie charts, no decorative visuals.** The paper's evaluators
  penalize these.
- **Every figure MUST have a caption** in `captions.json`. The Section
  Writing Agent will fail-stop if a caption is missing for any figure
  referenced from the outline.
- **No `Figure N:` prefix** in captions — LaTeX adds it.
- **Never describe data you didn't plot.** The Plotting Agent must not
  hallucinate axes, baselines, or trends. Source-of-truth is
  `experimental_log.md` or `idea.md`.

## Pre-existing figures (PlotOn mode)

If `workspace/inputs/figures/` is non-empty, check whether any pre-existing
file matches a `figure_id` in the outline (by filename prefix). If so,
**copy** it into `workspace/figures/` as-is and **still generate a caption**
using the caption prompt. Only generate from scratch the figure_ids that
have no pre-existing counterpart.

## Resources

- `references/caption-prompt.md` — verbatim Caption Generation prompt from App. F.1
- `references/plotting-pipeline.md` — the full few-shot → render → critique → caption loop
- `references/chart-patterns.md` — matplotlib style + chart type recipes
- `references/diagram-patterns.md` — conceptual diagram recipes
- `references/aspect-ratios.md` — pixel targets for each of the 12 allowed ratios at 300 DPI
- `references/paperbanana-cookbook.md` — **NEW** PaperBanana setup, usage, cost notes, attribution
- `scripts/render_matplotlib.py` — render a JSON plot spec → PNG (matplotlib fallback)
- `scripts/render_diagram.py` — render a JSON diagram spec → PNG (matplotlib fallback)
- `scripts/paperbanana_render.py` — **NEW** PaperBanana backbone wrapper (reads `PAPERBANANA_PATH` from env)

More from Ar9av/PaperOrchestra

SkillDescription
agent-research-aggregatorPre-pipeline aggregator that scans AI agent cache directories (.claude, .cursor, .antigravity, .openclaw) or any user-specified directory for experimentation logs, extracts insights and numeric results, and formats them as PaperOrchestra-ready inputs (idea.md + experimental_log.md). TRIGGER when the user says "aggregate my agent logs for paper writing", "extract experiments from my coding agent history", "prepare PaperOrchestra inputs from my cache", "turn my agent logs into a paper", mentions a folder or directory they want to use as the basis for a paper, or wants to run PaperOrchestra but only has scattered agent experiment histories rather than structured inputs. Run this BEFORE paper-orchestra. Also called automatically by paper-orchestra when workspace/inputs/idea.md or workspace/inputs/experimental_log.md are missing.
content-refinement-agentStep 5 of the PaperOrchestra pipeline (arXiv:2604.05018). Iteratively refine drafts/paper.tex by simulating peer review and applying targeted revisions, with strict accept/revert halt rules, deterministic 0-100 decision bands (Accept/Minor/Major/Reject) that drive a target-met early stop, and a Devil's Advocate concession-threshold guard that blocks acceptance on unresolved critical findings. Maintains a worklog and snapshots each iteration so revert is real, not symbolic. TRIGGER when the orchestrator delegates Step 5 or when the user asks to "refine the draft", "iterate on the paper", or "run peer review on this paper".
literature-review-agentStep 3 of the PaperOrchestra pipeline (arXiv:2604.05018). Execute the literature search strategy from outline.json — discover candidate papers via web search, verify them through Semantic Scholar (Levenshtein > 70 fuzzy title match, temporal cutoff, dedup by paperId), cross-corroborate against Crossref + OpenAlex to flag hallucinated citations, build a BibTeX file, and draft Introduction + Related Work using ≥90% of the verified pool. Runs in parallel with the plotting-agent. TRIGGER when the orchestrator delegates Step 3 or when the user asks to "find citations for my paper", "draft the related work", or "build the bibliography".
outline-agentStep 1 of the PaperOrchestra pipeline (arXiv:2604.05018). Convert (idea.md, experimental_log.md, template.tex, conference_guidelines.md) into a strict JSON outline containing a plotting plan, literature search plan (Intro + Related Work), and section-level writing plan with citation hints. TRIGGER when the orchestrator delegates Step 1 or when the user asks to "outline a paper from raw materials" or "generate the paper structure".
paper-autoratersRun the four paper-quality autoraters from PaperOrchestra (arXiv:2604.05018, App. F.3) — Citation F1 (P0/P1 partition + Precision/Recall/F1), Literature Review Quality (6-axis 0-100 with anti-inflation rules), SxS Overall Paper Quality (side-by-side), and SxS Literature Review Quality (side-by-side). TRIGGER when the user asks to "score this paper draft", "evaluate against the benchmark", "compare two papers", or "run the autoraters".
paper-orchestraOrchestrate the full PaperOrchestra (Song et al., 2026, arXiv:2604.05018) five-agent pipeline to turn unstructured research materials (idea, experimental log, LaTeX template, conference guidelines, optional figures) into a submission-ready LaTeX manuscript and compiled PDF. TRIGGER when the user asks to "write a paper from my experiments", "turn this idea and these results into a paper", "generate a conference submission", "run paper-orchestra on X", or otherwise wants the end-to-end paper-writing pipeline. Coordinates the outline-agent, plotting-agent, literature-review-agent, section-writing-agent, and content-refinement-agent skills.
paper-writing-benchReverse-engineer raw materials (Sparse idea, Dense idea, experimental log) from an existing AI research paper to build a benchmark case for evaluating paper-writing pipelines. Replicates the PaperWritingBench dataset construction procedure from arXiv:2604.05018 §3 / App. C. TRIGGER when the user asks to "build a benchmark case from this paper", "reverse-engineer raw materials", or "evaluate my pipeline against PaperWritingBench".
section-writing-agentStep 4 of the PaperOrchestra pipeline (arXiv:2604.05018). ONE single multimodal LLM call that drafts the remaining paper sections (Abstract, Methodology, Experiments, Conclusion), extracts numeric values from experimental_log.md into LaTeX booktabs tables, splices the generated figures from Step 2, and merges everything into the template that already contains Intro + Related Work from Step 3. TRIGGER when the orchestrator delegates Step 4 or when the user asks to "write the methodology and experiments sections" or "fill in the rest of the paper".