-
Notifications
You must be signed in to change notification settings - Fork 3
Home
Matplotlib-inspired charting for .NET. MatPlotLibNet renders charts on the server as SVG, PNG, PDF or
animated GIF. It ships an MCP server, so an AI agent can render charts with it. It has 83 series types, 13 map
projections with embedded Natural Earth data, 30 themes, LaTeX-style MathText, O(1) streaming with 58 technical
indicators, a control room (Plt.OpsDashboard(): KPI tiles, state timelines, a service-topology panel and one shared trend window), and
native controls for Blazor, WPF, MAUI, Avalonia, Uno and ASP.NET Core. The API is fluent and works with dependency
injection. There is no JavaScript framework, no WebView and no SaaS.
1.18.0 is the current release. Charts now draw inside a Verso notebook
cell. Verso is the open-source notebook built to replace Polyglot Notebooks, and MatPlotLibNet.Verso is an
extension you install from its Extensions panel: after that, a cell that ends on a figure — or on the builder
that makes one, without .Build() — shows the chart instead of a line of type names. A chart fills the width of
the cell, and one taller than the cell can show gets a scroll box rather than being squeezed into a size nobody
chose. The package carries the extension and nothing else, because a notebook loads an extension in its own
context and a second copy of the charting library there would be a different Figure from the cell's.
MatPlotLibNet.Notebooks stands still at the version it reached — the runtime under Polyglot Notebooks has
ended — and notebook work belongs in Verso now.
1.17.1 was a patch on top of it. A clicked data point now reaches your own code: the WPF, Avalonia and Uno
controls and the SignalR route all hand it over with the series it belongs to, its value and where it was, so you
can open a detail panel or select the matching row beside the chart. The control room gained a service-topology
panel, GroupedBar draws several bars per category in one call, and DensityScatter colours a scatter by how
crowded each part of it is. Three accessible colour sequences arrived — petroff6, petroff8 and petroff10 —
whose colours stay apart for colour-blind readers and in grayscale. All fourteen packages now carry an icon and
release notes, and the documentation has a page that
translates matplotlib into C#, call by call.
1.17 draws text in any script. Arabic and Hebrew labels draw correctly with
the bundled font: the letters join, the words read right to left, and a number or a Latin word inside them stays
where a reader expects it. The Unicode bidi algorithm is implemented in full and checked against Unicode's own
861,948 test cases; HarfBuzz shapes each run. SkiaFonts.Register(path) adds a font file for Devanagari, Thai,
Chinese and other scripts, and the MCP server reads font files from MATPLOTLIBNET_FONTS. Latin text is now
kerned, so text widths changed by up to 2 px per letter pair. See International Text.
1.16 added a data table beside every chart, for readers who cannot see the picture. figure.ToDataTables()
returns the figure's data as tables with typed columns. Each table can write itself out as HTML, Markdown or CSV,
and every host serves it. The same release fixed the streaming series, so a snapshot can no longer show a point
or a candle that never existed. See Accessibility.
1.15, the release before it, made the library usable by AI agents. It added MatPlotLibNet.Mcp, a Model
Context Protocol server that a host starts over stdio, so Claude or VS Code can render any of these chart types
from a JSON spec and look at the result. It is listed in the official MCP Registry as
io.github.xkqg/matplotlibnet. See MCP Server.
1.14, before that, was control-room work. It added the control-room pack itself, plus the fixes and extensions the pack needed. A secondary Y axis is fully supported, streaming series render in SVG, and 3-D axis titles no longer overlap their own labels. Every tile in a row uses the same layout. A hidden axis reserves no room, so a row of tiles is as wide as it looks. · NuGet · Changelog · License: MIT
dotnet add package MatPlotLibNetPlt.Create()
.AddSubPlot(1, 1, 1, ax => ax.Plot(x, y, s => s.Label = "signal"))
.SaveSvg("chart.svg");| Page | For |
|---|---|
| Getting Started | install, first chart, output formats, subplots |
| Fluent Cheatsheet | one page: Plt · FigureBuilder · AxesBuilder
|
| Chart Types | all 83 series with code — including the control room |
| Package Map | which of the 14 NuGet + 3 npm packages you need |
| Styling · MatplotlibThemes | themes, colours, fonts, layout |
| Advanced | animation, geo projections, MathText, DI |
| Streaming | live data, O(1) ring buffers, indicators |
| Bidirectional SignalR | push charts to Blazor / Angular / React / Vue |
| Interactive Controls · Keyboard Shortcuts | pan, zoom, brush-select, hotkeys |
| Notebooks | Polyglot / Jupyter |
| Accessibility | The data table beside the chart, ARIA, contrast, screen readers |
| Benchmarks | render and export timings |
| Roadmap · Contributing | where it is going, how to help |
Also: Playground · From matplotlib to C# · Cookbook · API Reference.
| You are… | You get… |
|---|---|
| Blazor / ASP.NET Core |
<MplChart> and <MplLiveChart>, SignalR push, a REST endpoint — wired with standard DI |
| WPF / MAUI / Avalonia / Uno | native controls (SkiaSharp or Microsoft.Maui.Graphics), pan / zoom / brush-select, no WebView |
| Data scientist | inline SVG in notebooks, plotting straight from Microsoft.Data.Analysis.DataFrame
|
| Trading / finance | candlestick, OHLC, 58 indicators, drawing tools, backtest panels, RRG |
| Ops / control room |
Plt.OpsDashboard() — KPI tiles, state timelines, a service-topology panel, one shared trend window |
| Backend / headless | render SVG, PNG, PDF or GIF server-side with zero UI dependencies |
| Angular / React / Vue | TypeScript clients on the same hub and the same chart definitions |
MatPlotLibNet is not a JavaScript wrapper, not a WebView host and not a hosted service. Charts are built and rendered in .NET. Only a picture or a chart definition leaves the process.
Every class passes a strict per-class coverage gate of at least 90 % line and branch coverage. That is currently 706 classes at 99.6 % line and 97.5 % branch coverage, across 11,757 tests. Rendering is verified against matplotlib pixel-fidelity fixtures.
If you have a question or something is missing, open a Discussion or an Issue. Releases follow what people actually need.
MatPlotLibNet 1.18.0