{"id":46585156,"url":"https://github.com/dartworklabs/dartwork-mpl","last_synced_at":"2026-06-08T04:01:07.728Z","repository":{"id":227864183,"uuid":"772569197","full_name":"dartworklabs/dartwork-mpl","owner":"dartworklabs","description":"Thin matplotlib layer for publication-quality figures — physical-width API, OKLCH color system, content-aware layout, and an MCP server for AI agents.","archived":false,"fork":false,"pushed_at":"2026-06-07T08:08:38.000Z","size":300153,"stargazers_count":3,"open_issues_count":11,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-07T08:15:08.237Z","etag":null,"topics":["charts","color-palette","data-visualization","matplotlib","matplotlib-style","mcp","plotting","scientific-visualization","visualization-library"],"latest_commit_sha":null,"homepage":"https://dartworklabs.github.io/dartwork-mpl/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dartworklabs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2024-03-15T13:03:38.000Z","updated_at":"2026-06-07T07:59:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"a64707da-7a44-499f-98f6-ed9be675651d","html_url":"https://github.com/dartworklabs/dartwork-mpl","commit_stats":null,"previous_names":["dartwork-repo/dartwork-mpl","dartworklabs/dartwork-mpl"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/dartworklabs/dartwork-mpl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dartworklabs%2Fdartwork-mpl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dartworklabs%2Fdartwork-mpl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dartworklabs%2Fdartwork-mpl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dartworklabs%2Fdartwork-mpl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dartworklabs","download_url":"https://codeload.github.com/dartworklabs/dartwork-mpl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dartworklabs%2Fdartwork-mpl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34047266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["charts","color-palette","data-visualization","matplotlib","matplotlib-style","mcp","plotting","scientific-visualization","visualization-library"],"created_at":"2026-03-07T12:03:45.276Z","updated_at":"2026-06-08T04:01:07.721Z","avatar_url":"https://github.com/dartworklabs.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dartwork-mpl\n\n[![PyPI version](https://img.shields.io/pypi/v/dartwork-mpl.svg)](https://pypi.org/project/dartwork-mpl/)\n[![Python versions](https://img.shields.io/pypi/pyversions/dartwork-mpl.svg)](https://pypi.org/project/dartwork-mpl/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![CI](https://github.com/dartworklabs/dartwork-mpl/actions/workflows/ci.yml/badge.svg)](https://github.com/dartworklabs/dartwork-mpl/actions/workflows/ci.yml)\n[![Docs](https://github.com/dartworklabs/dartwork-mpl/actions/workflows/docs.yml/badge.svg)](https://dartworklabs.github.io/dartwork-mpl/)\n\n**Publication-quality matplotlib — a thin utility layer, not a wrapper.**\n\n`dartwork-mpl` keeps `Figure` / `Axes` 100% native and adds the parts matplotlib\nmakes tedious: a physical-width geometry API, curated style presets, an OKLCH-aware\ncolor system, deterministic content-aware layout, visual validation, and a\nfirst-class integration for AI coding assistants (an MCP server + a bundled prompt\ncorpus). You never learn a new plotting API — you keep writing matplotlib, just\nwithout the friction.\n\n```python\nimport matplotlib.pyplot as plt\nimport dartwork_mpl as dm\n\ndm.style.use(\"scientific\")                                       # 1. curated preset\nfig, ax = plt.subplots(figsize=dm.figsize(\"13cm\", \"standard\"))   # 2. physical width × aspect\nax.plot(x, y, color=\"oc.blue5\", lw=dm.lw(0))\nax.set_xlabel(\"Time [s]\")\ndm.simple_layout(fig)                                            # 3. content-aware margins\ndm.save_formats(fig, \"figure\", formats=(\"svg\", \"png\", \"pdf\"))    # 4. multi-format save\n```\n\nThat four-step pattern — **preset → `figsize(width, aspect)` → `simple_layout` →\n`save_formats`** — is the whole workflow. No `tight_layout()`, no hand-tuned\n`figsize=(w, h)` arithmetic, no `dpi=` guesswork.\n\n\u003cbr/\u003e\n\n## Installation\n\n```shell\npip install dartwork-mpl        # or:  uv add dartwork-mpl\n```\n\nRequires Python 3.10+. The core install is intentionally lean; add an extra only\nwhen you need it:\n\n| Extra        | Enables                                   | Pulls in              |\n| ------------ | ----------------------------------------- | --------------------- |\n| `[notebook]` | `dm.show()` inline SVG display in Jupyter | `ipython`             |\n| `[mcp]`      | the MCP server for AI assistants          | `fastmcp`, `httpx`    |\n| `[ui]`       | the interactive parameter viewer          | `fastapi`, `uvicorn`  |\n\n```shell\npip install \"dartwork-mpl[notebook]\"   # or [mcp], [ui]\n```\n\n\u003cbr/\u003e\n\n## Highlights\n\n- **Geometry, decoupled from inches.** `dm.figsize(\"13cm\", \"standard\")` takes a\n  physical width (cm / in / mm / pt, or `dm.col1` = 9 cm / `dm.col2` = 17 cm) and\n  one of six aspect tokens (`square / portrait / standard / golden / wide /\n  cinema`); the height follows. Bare numbers are rejected so the unit is always\n  explicit.\n- **Deterministic layout.** `simple_layout(fig)` measures every visible artist and\n  places the GridSpec arithmetically — reproducible across machines, unlike\n  `tight_layout()`'s heuristics. `margin=\"2%\"` (or `dm.mm(2)`) adds a buffer.\n- **OKLCH-aware color.** Named palettes (`oc.*` Open Color, `tw.*` Tailwind,\n  `md.*`, `ad.*`, `cu.*`, `pr.*`) plus a `Color` class spanning OKLab / OKLCH /\n  RGB / hex with perceptual interpolation (`cspace`) and gamut-correct mapping.\n- **Curated styling.** Seven presets (`scientific`, `report`, `presentation`, …),\n  each with a Korean `-kr` variant, and preset-relative scaling helpers `fs` /\n  `fw` / `lw` so literals never drift when you switch themes.\n- **Validation \u0026 export.** `validate_figure(fig)` flags overflow, text/legend\n  overlap, tick crowding, and empty axes — invisible failures in headless agent\n  pipelines. `save_formats(fig, ...)` writes SVG / PNG / PDF / EPS at once.\n- **AI-native.** A bundled [MCP](https://modelcontextprotocol.io) server exposes\n  lint + auto-fix, figure validation, color lookup, and the live policy corpus to\n  Claude Code / Cursor / Windsurf. No-MCP agents read the same corpus from disk.\n- **Batteries included.** Material Design Icons + Font Awesome 6 fonts, ready-made\n  plot templates (`plot_diverging_bar`, …), and a FastAPI viewer for live tuning.\n\n\u003cbr/\u003e\n\n## Core API at a glance\n\n```python\nimport dartwork_mpl as dm\n\n# ── Geometry ──────────────────────────────────────────────────────────\ndm.figsize(\"13cm\", \"wide\")          # width × aspect token  → inch tuple\ndm.figsize(\"13cm\", 0.6)             # ...or a numeric ratio / \"8cm\" / dm.cm(8)\ndm.cm(13); dm.mm(170); dm.inch(4.6); dm.pt(24)   # Length values\ndm.col1; dm.col2                    # 9 cm / 17 cm academic-column sugar\n\n# ── Styling \u0026 scaling ─────────────────────────────────────────────────\ndm.style.use(\"scientific\")          # apply a preset\ndm.style.stack([\"base\", \"font-scientific\", \"lang-kr\"])   # compose\ndm.fs(2); dm.fw(1); dm.lw(-0.3)     # preset-relative font size / weight / line width\n\n# ── Color ─────────────────────────────────────────────────────────────\nax.plot(x, y, color=\"oc.blue5\")     # named palettes register with matplotlib\ndm.color(\"oc.blue5\")                # parse name / \"#4285F4\" / \"rgb(...)\" / \"oklch(...)\"\ndm.oklch(0.7, 0.15, 150); dm.rgb(66, 133, 244); dm.hex(\"#4285F4\")\ndm.cspace(\"#FF0000\", \"#0000FF\", n=5, space=\"oklch\")      # perceptual interpolation\ndm.mix_colors(\"oc.blue5\", \"white\", alpha=0.35)\n\n# ── Layout \u0026 annotation ───────────────────────────────────────────────\ndm.simple_layout(fig)               # deterministic content-aware margins\ndm.simple_layout(fig, margin=\"2%\", gs=gs)   # buffer + target a GridSpec\ndm.label_axes(axes)                 # (a) (b) (c) panel labels\ndm.arrow_axis(ax, \"x\", \"Cost\")      # Low ◄── Cost ──► High\n\n# ── Validate, export, icons ───────────────────────────────────────────\ndm.validate_figure(fig)             # overflow / overlap / tick-crowding / empty\ndm.save_formats(fig, \"fig\", formats=(\"png\", \"svg\", \"pdf\"), dpi=300)\nmdi = dm.icon_font(\"mdi\")           # also \"fa-solid\" / \"fa-regular\" / \"fa-brands\"\n\n# ── Plot templates ────────────────────────────────────────────────────\nfrom dartwork_mpl.templates import plot_diverging_bar\nfig, ax = plot_diverging_bar(labels=[\"A\", \"B\"], neg_values=[-30, -15], pos_values=[40, 55])\n```\n\nSee the [usage guide](https://dartworklabs.github.io/dartwork-mpl/usage_guide/index.html)\nand [API reference](https://dartworklabs.github.io/dartwork-mpl/api/index.html) for\nthe full surface.\n\n\u003cbr/\u003e\n\n## Style presets\n\n| Preset         | Use case                                          |\n| -------------- | ------------------------------------------------- |\n| `scientific`   | Compact fonts for academic papers and journals    |\n| `report`       | Reports and dashboards, cleaner spines            |\n| `minimal`      | Tufte-style, data-ink focus — no spines or ticks  |\n| `presentation` | Large fonts for projected slides                  |\n| `poster`       | Extra-large fonts and thick lines for posters     |\n| `web`          | On-screen readability for docs and notebooks      |\n| `dark`         | Dark backgrounds for Jupyter and dark-mode slides |\n\nEach has a Korean `-kr` variant (`scientific-kr`, `report-kr`, …) with Korean-aware\nfonts. List them with `dm.list_styles()`.\n\n\u003cbr/\u003e\n\n## AI-assisted development (MCP)\n\ndartwork-mpl ships a built-in **Model Context Protocol** server so AI coding\nassistants pull the current policy guides, color palettes, lint catalog, and\nhelper tools straight into the chat — no copy-pasting docs. It exposes **13 tools**\n(lint + auto-fix, figure validation, render, color lookup, info), **12 resources +\n3 resource templates** (the prompt corpus + 18 plot templates), and **2 prompts**.\n\n```shell\npip install \"dartwork-mpl[mcp]\"     # installs fastmcp + httpx; adds the dartwork-mpl-mcp script\n```\n\nPoint your client at the `dartwork-mpl-mcp` console script — e.g. Claude Code\n(`~/.claude.json`) or Cursor (`~/.cursor/mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"dartwork-mpl\": { \"command\": \"dartwork-mpl-mcp\" }\n  }\n}\n```\n\nRestart the client and ask it to list its MCP resources to confirm. Windsurf,\nAntigravity, generic stdio setups, the full tool/resource catalog, and the\nlocal-clone variant are covered in\n[`docs/integrations/mcp_server.md`](docs/integrations/mcp_server.md).\n\n\u003e **No MCP?** The same corpus is bundled in the wheel and reachable from Python —\n\u003e `dm.get_agent_doc(\"llms-full\")` (also `\"AGENTS\"`, `\"CLAUDE\"`, `\"llms\"`) returns\n\u003e the text, `dm.agent_doc_path(name)` its path. The repo-root\n\u003e [`CLAUDE.md`](CLAUDE.md) / [`AGENTS.md`](AGENTS.md) / [`llms.txt`](llms.txt)\n\u003e (per the [llmstxt.org](https://llmstxt.org) spec) are the 30-second onboarding.\n\n\u003cbr/\u003e\n\n## Documentation\n\n📚 **[Full documentation](https://dartworklabs.github.io/dartwork-mpl/)**\n\n- [Quickstart](https://dartworklabs.github.io/dartwork-mpl/usage_guide/quickstart.html) — install, first figure, save\n- [Usage guide](https://dartworklabs.github.io/dartwork-mpl/usage_guide/index.html) — width/aspect, layout, color, patterns\n- [Color system](https://dartworklabs.github.io/dartwork-mpl/color_system/index.html) — palettes, OKLCH, colormaps\n- [Example gallery](https://dartworklabs.github.io/dartwork-mpl/examples_gallery/index.html) — rendered, copy-pasteable\n- [API reference](https://dartworklabs.github.io/dartwork-mpl/api/index.html) — every public function and class\n- [Design philosophy](https://dartworklabs.github.io/dartwork-mpl/philosophy/index.html) — why thin utilities, not a wrapper\n\n\u003cbr/\u003e\n\n## Project layout\n\n```\nsrc/dartwork_mpl/\n├── units.py / scale.py        # figsize, cm/mm/inch/pt, col1/col2 · fs/fw/lw\n├── style.py                   # Style class + preset management\n├── colors/                    # Color (OKLab/OKLCH/RGB/hex) + named palettes\n├── layout.py / annotation.py  # simple_layout, label_axes, arrow_axis\n├── validate.py / lint.py      # validate_figure · lint + migrate_legacy_code\n├── io.py / formatting.py      # save_formats, show · format_axis_*\n├── icon.py / font.py / cmap.py / diagnostics/   # fonts, colormaps, viz helpers\n├── templates/ / helpers/      # plot templates · high-level composition helpers\n├── agent.py / prompt.py       # bundled LLM corpus · prompt guides\n├── mcp/                       # MCP server (server / resources / tools / prompts)\n├── ui/                        # interactive FastAPI viewer\n└── asset/                     # bundled styles, colors, fonts, icons, prompts\n```\n\n\u003cbr/\u003e\n\n## Contributing \u0026 issues\n\nBug reports and feature requests go to the\n[GitHub issue tracker](https://github.com/dartworklabs/dartwork-mpl/issues).\nReleased under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdartworklabs%2Fdartwork-mpl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdartworklabs%2Fdartwork-mpl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdartworklabs%2Fdartwork-mpl/lists"}