anyplot is an open catalogue of plotting examples. Each plot type starts as one library-agnostic specification, and an AI pipeline writes, renders, reviews, and maintains its implementations in 15 plotting libraries across Python, R, Julia, and JavaScript. On anyplot.ai, you compare the libraries side by side and copy working code.
Built by Markus Neusinger.
One spec in 15 libraries: the site's live preview card for ridgeline-basic shows six of them; the spec page shows all 15.
| Specifications | Implementations | Libraries | Languages |
|---|---|---|---|
| 325 | 4,863 | 15 | 4 |
Counted on 2026-11-02 from the public API (https://api.anyplot.ai/stats); the stats page
shows the current numbers. 316 of the 325 specs exist in all 15 libraries; the other nine, mostly 3D and map plots,
lack one or two.
| Language | Libraries |
|---|---|
| Python | matplotlib, seaborn, plotly, bokeh, altair, plotnine, pygal, lets-plot |
| R | ggplot2 |
| Julia | Makie.jl |
| JavaScript | Chart.js, D3.js, ECharts, Highcharts, MUI X Charts (React) |
- Compare libraries. Each spec page shows the same plot in every library, usually all 15, in a light and a dark theme, each with its code and its review score.
- Search and filter. A typo-tolerant search matches spec titles and tag values, and the matches become filters: language, library, plot type, data structure, domain, and features, plus implementation tags such as techniques, dependencies, and styling.
- Explore by similarity. The map draws the catalogue as a graph of specs linked by tag similarity, and every spec page lists related specs.
- Use it from an AI assistant. The MCP server serves the same catalogue to coding agents.
AI writes every implementation, most of them Claude running in GitHub Actions. GitHub issues hold the state of each plot.
- Request. Someone opens an issue, from GitHub or from a link on anyplot.ai.
- Specification.
spec-create.ymlchecks for duplicates, assigns a spec ID and tags, and opens a pull request with the spec. The maintainer approves it on the issue. - Generation.
impl-generate.ymlwrites one implementation per library and renders it in both themes. - Review.
impl-review.ymlfirst runs automated checks: the code parses and runs, the image exists and isn't blank, and the canvas has its target size. An AI reviewer then scores the render, blind to any earlier score, on a 100-point rubric of 24 criteria (prompts/quality-criteria.md): visual quality 30, design 20, spec compliance 15, data quality 15, code quality 10, and library mastery 10. - Repair. Below the bar,
impl-repair.ymlfixes the defects the review named, and the plot is reviewed again. - Merge.
impl-merge.ymlmerges the pull request, promotes the images from staging to production in Cloud Storage, and syncs PostgreSQL.
- A first review needs 90 of 100. Each repair lowers the bar by 10 points: 80, 70, 60, and 50 after the fourth and last repair. An implementation still below 50 is closed and marked failed.
- The rubric reserves 90 and more for a plot that "should genuinely impress a data visualization professional". The reviewer never sees the thresholds.
- Technical criteria start at full points and lose them only through a written defect line that names the criterion, the observed value, and the fix. Design and library criteria start at a default and rise only with named evidence.
- Code that fails to run, a blank image, clipped labels, or a static library faking interactivity scores 0.
- One exception to the bar: a review of 80 or more that names no defect and gives every technical criterion its full points is approved, because a repair would have nothing to fix.
daily-regen.yml regenerates the oldest part of the catalogue every night: by default the oldest spec in every
library, and since 2026-10-31 the two oldest single implementations instead. A regeneration replaces the live
implementation only when its review, which scores both versions, finds a fixed defect and no regression (the regen
gate).
For the labels, retries, and every workflow, see Workflows.
Status: experimental, open to every visitor since 2 November 2026.
On a plot page, choose use with my data and paste your own data. An agent adapts that plot's catalogue code to your data, renders it in a sandbox, reviews the render against the catalogue's rubric, repairs it once if needed, and returns the image and the code.
- Agents. A Google ADK service on Cloud Run. The model is Claude Haiku 5.5 through Vertex AI in the EU; Gemini 3.8 Flash is a configurable second arm. Runtimes exist for all 15 libraries.
- Sandboxed rendering. No model-written code runs in the agent service. A separate renderer runs it in Cloud Run sandboxes (gVisor): no network egress, no metadata server, and a read-only root filesystem. The renderer's service account holds no IAM role.
- Static validation. Before anything runs, a validator reads the code (Python's
ast, tree-sitter for R, Julia, and JavaScript) and refuses disallowed imports and calls. - Guard judges. A scope judge reads every typed message before any agent sees it and fails closed; a dataset judge checks pasted data and notes. Spend limits apply per user and per day, and a budget guard switches Vertex AI off when its monthly budget is reached.
- Evals. A model-regression harness runs synthetic, stress, and promoted real cases; separate evals score the scope judge and the data preparation.
- Content-free telemetry. Usage events hold only enums, buckets, counts, and IDs from closed sets. No message, data value, or column name reaches a line, and a test enforces it.
Read the agent network design, the agents README, and the telemetry reference.
anyplot runs an MCP (Model Context Protocol) server, so AI assistants can search the catalogue and fetch implementation code.
| Tool | What it does |
|---|---|
list_specs |
Lists all plot specifications |
search_specs_by_tags |
Finds specs by tags: plot type, data type, domain, features, library, and implementation tags |
get_spec_detail |
Returns a full specification with its implementations |
get_implementation |
Returns the code for one library |
list_libraries |
Lists the supported libraries |
get_tag_values |
Lists the values of a tag category |
Add it to your MCP client configuration, for example Claude Code's .mcp.json:
{
"mcpServers": {
"anyplot": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://api.anyplot.ai/mcp/"]
}
}
}The server speaks Streamable HTTP only. Clients with native support connect to https://api.anyplot.ai/mcp/ without
the mcp-remote bridge. The legacy SSE endpoint (https://api.anyplot.ai/sse/) has been removed. For details, see
MCP server.
| Area | Stack |
|---|---|
| Backend | Python 3.14, FastAPI, SQLAlchemy (async), PostgreSQL, Alembic |
| Frontend | React 19, TypeScript, Vite, MUI |
| Agents | Google ADK, Claude Haiku 5.5 on Vertex AI, Cloud Run sandboxes |
| Pipeline | GitHub Actions with Claude Code |
| Infrastructure | Cloud Run, Cloud SQL, Cloud Storage, Cloud Build, BigQuery, Cloudflare |
Each render runtime is pinned: Python by pyproject.toml and uv.lock, the JavaScript libraries by package.json and
package-lock.json, Julia by Project.toml and Manifest.toml, and R by a dated Posit Package Manager snapshot.
anyplot/
├── plots/ # One directory per plot type: spec, metadata, implementations
├── prompts/ # Generation and review prompts, the quality rubric
├── .github/workflows/ # The pipeline (spec-create, impl-*, daily-regen) and CI
├── api/ # FastAPI backend and the MCP server
├── app/ # React frontend
├── agents/ # "Use with my data": ADK agent service, sandbox renderer, evals
├── core/ # Shared Python logic: database, palette, checks
├── automation/ # Workflow scripts: sync, labels, the regen gate, the JS render harness
├── alembic/ # Database migrations
├── tests/ # Unit, integration, and end-to-end tests
├── infra/ # Cloudflare configuration
├── scripts/ # Maintenance scripts
├── tools/, changelog.d/ # Changelog tooling and one changelog fragment per pull request
├── agentic/ # Commands and docs for the coding agents that work on this repository
└── docs/ # Documentation
The root package.json and package-lock.json pin the JavaScript render runtime, and Project.toml and
Manifest.toml pin the Julia one. A plot directory looks like this:
plots/scatter-basic/
├── specification.md # Library-agnostic specification
├── specification.yaml # Tags, creation date, issue
├── metadata/ # Per-library quality score, review, preview URLs
└── implementations/
├── python/ # matplotlib.py, seaborn.py, … (8 files)
├── r/ggplot2.R
├── julia/makie.jl
└── javascript/ # chartjs.js, d3.js, echarts.js, highcharts.js, muix.tsx
For every directory, see Repository structure.
You contribute ideas, not code: the pipeline writes every implementation.
| Action | When to use | On anyplot.ai |
|---|---|---|
| Suggest a spec | Propose a new plot type | spec.suggest() on the home page and the specs list |
| Report a spec issue | A specification has a problem | "report issue" on the spec page |
| Report an implementation issue | One library's implementation has a problem | "report issue" on the spec page |
- Open an issue, on GitHub or through a link on anyplot.ai.
- The AI validates and processes it.
- The maintainer reviews and approves it.
- The pipeline generates or fixes the code, and the review gates it.
Don't open pull requests with plot code. A plot with quality problems usually needs a better spec, not hand-edited code. For details, see Contributing. To run the project locally, see the development guide.
- Vision: the product vision
- Workflows: the automation and its labels
- Agent network: the design of "Use with my data"
- Reference: API, MCP, database, repository structure, and style guide
- Documentation index: everything else
Most plotting libraries are fully open source. Highcharts is free for non-commercial use; commercial use requires a license from highcharts.com.
The project is under the MIT License; see LICENSE. The JetBrains Mono fonts bundled in
agents/anyplot/render/fonts/ for the footer strip of user plots are third-party files under the SIL Open Font License
1.1; see their notice.
- Website: anyplot.ai
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Analytics: public Plausible dashboard
Built by Markus Neusinger
