Design decisions, not syntax

The grammar of graphics with an agentic AI assistant — a live demonstration

Jon Minton

VisHub group meeting, EFI room 1.70

Tue 29 Sep 2026

The claim

  • The grammar of graphics is a design specification language, not an R package
  • Agentic AI can take over the language-specific implementation
  • That leaves the analyst’s attention on the design decisions: mappings, geoms, scales, facets, coords
  • Today: test that claim live, on a TidyTuesday dataset you choose

And then: tell me where it breaks.

The grammar travels

Implementation Language A grammar?
ggplot2 R Yes — Wickham’s layered grammar
plotnine Python Yes — near line-for-line port
Vega-Lite JSON / JS Yes — mark / encoding / layer
plotly JS / Python / R Layered, but not a true grammar

The spec is substrate-invariant: the same mapping rules compile to any row marked “Yes”.

Chatbot vs agent

Chatbot

  • Sees only what you paste in
  • Writes text for you to copy
  • Forgets between sessions

Agent (LLM in a code scaffold)

  • Sits in the project folder
  • Reads, writes and runs files: R, shell, git
  • Renders the figure — and looks at it
  • Follows written project instructions

Access — the supported route

  • Frontier models in code scaffolds: e.g. Claude Code or Codex — interchangeable here; the repo works with either, or both
  • At the University: ELM, the University’s own AI gateway, is the institutionally supported route
  • Nothing today depends on a particular vendor — the instructions and skills are plain text

One instruction file, plain-text skills

agentic-datavis-workshops/
├── AGENTS.md            ← single source of truth for any agent
├── CLAUDE.md            ← one line: @AGENTS.md
├── .claude/skills/
│   ├── tt-fetch/        ← fetch + describe a TidyTuesday week
│   └── gg-spec/         ← YAML spec → ggplot2 → render → look
└── .agents/skills/      ← symlinks, so Codex sees the same skills
  • A skill is a markdown procedure — readable by you, followed by the agent
  • Skills exist for consistent behaviour across sessions and across vendors

The spec: round 1

data: penguins
filter: "!is.na(bill_depth_mm)"
mapping:
  x: bill_length_mm
  y: bill_depth_mm
layers:
  - geom: point
    alpha: 0.6
  - geom: smooth
    stat: lm
    se: true
labs:
  title: "Do longer bills mean
          deeper bills?"
theme: minimal

Pooled: longer bills, shallower bills?

The spec: round 2 — one line added

mapping:
  x: bill_length_mm
  y: bill_depth_mm
  colour: species      # ← new
layers:
  - geom: point
    alpha: 0.6
  - geom: smooth
    stat: lm
    se: true
scales:
  colour: okabe-ito    # ← new

Simpson’s paradox: within every species the slope is positive.

Taste the cake, change the recipe

  • Recipe = the spec, the .qmd, the code. Cake = the rendered figure
  • Look at the cake; edit the recipe; re-bake
  • Hand-editing the output (Illustrator tweaks, pasted PNGs) = frankencake: unreproducible, untraceable
  • Git is the safety net: every spec revision is committed, diffable, reversible

Complementary strengths

People in the room The agent
Design judgement Meaning, audience, purpose Knows the conventions, not the point
Implementation Slow, syntax-bound Fast, multi-language
Looking Gestalt, “that’s wrong” Detail: clipped titles, overplotting
Iteration Purposeful Tireless, needs direction

A spectrum of autonomy

Far end: fully autonomous

  • The model chose datasets, questions, figures and words, unsteered
  • Loop: make → look → revise
  • Caught by looking: a title saying “fourfold” over bars showing tenfold; a density estimate collapsed on heaped data

https://jonminton.github.io/claude-fable-vision-ds-test/

Today: the other end

  • The room makes every design decision
  • The agent types, renders, and reports what it sees
  • Autonomous mode is a contrast, not the default

Live: you choose

Pre-cached (so bad wifi can’t sink it) — or name any other week:

Dataset Week Rows Decisions it provokes
Scottish Munros 2025-08-19 604 Pivot first; map coords (coord_fixed) vs height
UK Met Office stations 2025-10-21 39k Month: discrete or cyclic? 37 stations: facet, filter, map
How likely is ‘likely’? 2026-03-10 98k 19 phrases × probability: distribution geoms; axis order
  1. tt-fetch: fetch and describe the week’s data
  2. You dictate mappings → gg-spec compiles, renders, and we look
  3. Revise the spec; repeat

What to watch for — and critique

  • Visual judgement: does the agent notice when a render is wrong, or only when it’s broken?
  • Defaults as decisions: every unspecified scale, palette, bin width and axis range is a choice someone made
  • Faithful compilation: does the code do only what the spec says — or quietly “improve” it?
  • Provenance: can you trace each figure back to a spec, a decision, and a commit?
  • Where the grammar runs out: annotation, layout, interaction

Summing up

  • What worked? What did the agent get wrong, and who caught it?
  • Is a YAML spec a useful teaching object for the grammar?
  • What would you need to trust this in your own research?

Repo (public, clone it): https://github.com/JonMinton/agentic-datavis-workshops

Read: Wickham, A Layered Grammar of Graphics (2010) · ggplot2 book · Vega-Lite docs · plotnine · Wilkinson, The Grammar of Graphics (2005)