https://github.com/dartworklabs/dartwork-mpl
Thin matplotlib layer for publication-quality figures — physical-width API, OKLCH color system, content-aware layout, and an MCP server for AI agents.
https://github.com/dartworklabs/dartwork-mpl
charts color-palette data-visualization matplotlib matplotlib-style mcp plotting scientific-visualization visualization-library
Last synced: 9 days ago
JSON representation
Thin matplotlib layer for publication-quality figures — physical-width API, OKLCH color system, content-aware layout, and an MCP server for AI agents.
- Host: GitHub
- URL: https://github.com/dartworklabs/dartwork-mpl
- Owner: dartworklabs
- License: mit
- Created: 2024-03-15T13:03:38.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2026-06-07T08:08:38.000Z (10 days ago)
- Last Synced: 2026-06-07T08:15:08.237Z (10 days ago)
- Topics: charts, color-palette, data-visualization, matplotlib, matplotlib-style, mcp, plotting, scientific-visualization, visualization-library
- Language: Python
- Homepage: https://dartworklabs.github.io/dartwork-mpl/
- Size: 286 MB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# dartwork-mpl
[](https://pypi.org/project/dartwork-mpl/)
[](https://pypi.org/project/dartwork-mpl/)
[](https://opensource.org/licenses/MIT)
[](https://github.com/dartworklabs/dartwork-mpl/actions/workflows/ci.yml)
[](https://dartworklabs.github.io/dartwork-mpl/)
**Publication-quality matplotlib — a thin utility layer, not a wrapper.**
`dartwork-mpl` keeps `Figure` / `Axes` 100% native and adds the parts matplotlib
makes tedious: a physical-width geometry API, curated style presets, an OKLCH-aware
color system, deterministic content-aware layout, visual validation, and a
first-class integration for AI coding assistants (an MCP server + a bundled prompt
corpus). You never learn a new plotting API — you keep writing matplotlib, just
without the friction.
```python
import matplotlib.pyplot as plt
import dartwork_mpl as dm
dm.style.use("scientific") # 1. curated preset
fig, ax = plt.subplots(figsize=dm.figsize("13cm", "standard")) # 2. physical width × aspect
ax.plot(x, y, color="oc.blue5", lw=dm.lw(0))
ax.set_xlabel("Time [s]")
dm.simple_layout(fig) # 3. content-aware margins
dm.save_formats(fig, "figure", formats=("svg", "png", "pdf")) # 4. multi-format save
```
That four-step pattern — **preset → `figsize(width, aspect)` → `simple_layout` →
`save_formats`** — is the whole workflow. No `tight_layout()`, no hand-tuned
`figsize=(w, h)` arithmetic, no `dpi=` guesswork.
## Installation
```shell
pip install dartwork-mpl # or: uv add dartwork-mpl
```
Requires Python 3.10+. The core install is intentionally lean; add an extra only
when you need it:
| Extra | Enables | Pulls in |
| ------------ | ----------------------------------------- | --------------------- |
| `[notebook]` | `dm.show()` inline SVG display in Jupyter | `ipython` |
| `[mcp]` | the MCP server for AI assistants | `fastmcp`, `httpx` |
| `[ui]` | the interactive parameter viewer | `fastapi`, `uvicorn` |
```shell
pip install "dartwork-mpl[notebook]" # or [mcp], [ui]
```
## Highlights
- **Geometry, decoupled from inches.** `dm.figsize("13cm", "standard")` takes a
physical width (cm / in / mm / pt, or `dm.col1` = 9 cm / `dm.col2` = 17 cm) and
one of six aspect tokens (`square / portrait / standard / golden / wide /
cinema`); the height follows. Bare numbers are rejected so the unit is always
explicit.
- **Deterministic layout.** `simple_layout(fig)` measures every visible artist and
places the GridSpec arithmetically — reproducible across machines, unlike
`tight_layout()`'s heuristics. `margin="2%"` (or `dm.mm(2)`) adds a buffer.
- **OKLCH-aware color.** Named palettes (`oc.*` Open Color, `tw.*` Tailwind,
`md.*`, `ad.*`, `cu.*`, `pr.*`) plus a `Color` class spanning OKLab / OKLCH /
RGB / hex with perceptual interpolation (`cspace`) and gamut-correct mapping.
- **Curated styling.** Seven presets (`scientific`, `report`, `presentation`, …),
each with a Korean `-kr` variant, and preset-relative scaling helpers `fs` /
`fw` / `lw` so literals never drift when you switch themes.
- **Validation & export.** `validate_figure(fig)` flags overflow, text/legend
overlap, tick crowding, and empty axes — invisible failures in headless agent
pipelines. `save_formats(fig, ...)` writes SVG / PNG / PDF / EPS at once.
- **AI-native.** A bundled [MCP](https://modelcontextprotocol.io) server exposes
lint + auto-fix, figure validation, color lookup, and the live policy corpus to
Claude Code / Cursor / Windsurf. No-MCP agents read the same corpus from disk.
- **Batteries included.** Material Design Icons + Font Awesome 6 fonts, ready-made
plot templates (`plot_diverging_bar`, …), and a FastAPI viewer for live tuning.
## Core API at a glance
```python
import dartwork_mpl as dm
# ── Geometry ──────────────────────────────────────────────────────────
dm.figsize("13cm", "wide") # width × aspect token → inch tuple
dm.figsize("13cm", 0.6) # ...or a numeric ratio / "8cm" / dm.cm(8)
dm.cm(13); dm.mm(170); dm.inch(4.6); dm.pt(24) # Length values
dm.col1; dm.col2 # 9 cm / 17 cm academic-column sugar
# ── Styling & scaling ─────────────────────────────────────────────────
dm.style.use("scientific") # apply a preset
dm.style.stack(["base", "font-scientific", "lang-kr"]) # compose
dm.fs(2); dm.fw(1); dm.lw(-0.3) # preset-relative font size / weight / line width
# ── Color ─────────────────────────────────────────────────────────────
ax.plot(x, y, color="oc.blue5") # named palettes register with matplotlib
dm.color("oc.blue5") # parse name / "#4285F4" / "rgb(...)" / "oklch(...)"
dm.oklch(0.7, 0.15, 150); dm.rgb(66, 133, 244); dm.hex("#4285F4")
dm.cspace("#FF0000", "#0000FF", n=5, space="oklch") # perceptual interpolation
dm.mix_colors("oc.blue5", "white", alpha=0.35)
# ── Layout & annotation ───────────────────────────────────────────────
dm.simple_layout(fig) # deterministic content-aware margins
dm.simple_layout(fig, margin="2%", gs=gs) # buffer + target a GridSpec
dm.label_axes(axes) # (a) (b) (c) panel labels
dm.arrow_axis(ax, "x", "Cost") # Low ◄── Cost ──► High
# ── Validate, export, icons ───────────────────────────────────────────
dm.validate_figure(fig) # overflow / overlap / tick-crowding / empty
dm.save_formats(fig, "fig", formats=("png", "svg", "pdf"), dpi=300)
mdi = dm.icon_font("mdi") # also "fa-solid" / "fa-regular" / "fa-brands"
# ── Plot templates ────────────────────────────────────────────────────
from dartwork_mpl.templates import plot_diverging_bar
fig, ax = plot_diverging_bar(labels=["A", "B"], neg_values=[-30, -15], pos_values=[40, 55])
```
See the [usage guide](https://dartworklabs.github.io/dartwork-mpl/usage_guide/index.html)
and [API reference](https://dartworklabs.github.io/dartwork-mpl/api/index.html) for
the full surface.
## Style presets
| Preset | Use case |
| -------------- | ------------------------------------------------- |
| `scientific` | Compact fonts for academic papers and journals |
| `report` | Reports and dashboards, cleaner spines |
| `minimal` | Tufte-style, data-ink focus — no spines or ticks |
| `presentation` | Large fonts for projected slides |
| `poster` | Extra-large fonts and thick lines for posters |
| `web` | On-screen readability for docs and notebooks |
| `dark` | Dark backgrounds for Jupyter and dark-mode slides |
Each has a Korean `-kr` variant (`scientific-kr`, `report-kr`, …) with Korean-aware
fonts. List them with `dm.list_styles()`.
## AI-assisted development (MCP)
dartwork-mpl ships a built-in **Model Context Protocol** server so AI coding
assistants pull the current policy guides, color palettes, lint catalog, and
helper tools straight into the chat — no copy-pasting docs. It exposes **13 tools**
(lint + auto-fix, figure validation, render, color lookup, info), **12 resources +
3 resource templates** (the prompt corpus + 18 plot templates), and **2 prompts**.
```shell
pip install "dartwork-mpl[mcp]" # installs fastmcp + httpx; adds the dartwork-mpl-mcp script
```
Point your client at the `dartwork-mpl-mcp` console script — e.g. Claude Code
(`~/.claude.json`) or Cursor (`~/.cursor/mcp.json`):
```json
{
"mcpServers": {
"dartwork-mpl": { "command": "dartwork-mpl-mcp" }
}
}
```
Restart the client and ask it to list its MCP resources to confirm. Windsurf,
Antigravity, generic stdio setups, the full tool/resource catalog, and the
local-clone variant are covered in
[`docs/integrations/mcp_server.md`](docs/integrations/mcp_server.md).
> **No MCP?** The same corpus is bundled in the wheel and reachable from Python —
> `dm.get_agent_doc("llms-full")` (also `"AGENTS"`, `"CLAUDE"`, `"llms"`) returns
> the text, `dm.agent_doc_path(name)` its path. The repo-root
> [`CLAUDE.md`](CLAUDE.md) / [`AGENTS.md`](AGENTS.md) / [`llms.txt`](llms.txt)
> (per the [llmstxt.org](https://llmstxt.org) spec) are the 30-second onboarding.
## Documentation
📚 **[Full documentation](https://dartworklabs.github.io/dartwork-mpl/)**
- [Quickstart](https://dartworklabs.github.io/dartwork-mpl/usage_guide/quickstart.html) — install, first figure, save
- [Usage guide](https://dartworklabs.github.io/dartwork-mpl/usage_guide/index.html) — width/aspect, layout, color, patterns
- [Color system](https://dartworklabs.github.io/dartwork-mpl/color_system/index.html) — palettes, OKLCH, colormaps
- [Example gallery](https://dartworklabs.github.io/dartwork-mpl/examples_gallery/index.html) — rendered, copy-pasteable
- [API reference](https://dartworklabs.github.io/dartwork-mpl/api/index.html) — every public function and class
- [Design philosophy](https://dartworklabs.github.io/dartwork-mpl/philosophy/index.html) — why thin utilities, not a wrapper
## Project layout
```
src/dartwork_mpl/
├── units.py / scale.py # figsize, cm/mm/inch/pt, col1/col2 · fs/fw/lw
├── style.py # Style class + preset management
├── colors/ # Color (OKLab/OKLCH/RGB/hex) + named palettes
├── layout.py / annotation.py # simple_layout, label_axes, arrow_axis
├── validate.py / lint.py # validate_figure · lint + migrate_legacy_code
├── io.py / formatting.py # save_formats, show · format_axis_*
├── icon.py / font.py / cmap.py / diagnostics/ # fonts, colormaps, viz helpers
├── templates/ / helpers/ # plot templates · high-level composition helpers
├── agent.py / prompt.py # bundled LLM corpus · prompt guides
├── mcp/ # MCP server (server / resources / tools / prompts)
├── ui/ # interactive FastAPI viewer
└── asset/ # bundled styles, colors, fonts, icons, prompts
```
## Contributing & issues
Bug reports and feature requests go to the
[GitHub issue tracker](https://github.com/dartworklabs/dartwork-mpl/issues).
Released under the [MIT License](LICENSE).