Skip to content
H.P. Gansevoort edited this page Oct 24, 2026 · 90 revisions

MatPlotLibNet Wiki

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, seventeen charts built from them in one call, 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.22.0 is the current release. Several series can now share one colour from the theme's cycle instead of each taking the next one. A Kaplan-Meier curve draws a confidence band and censor marks in its own colour, and two new verbs use the same mechanism: Raincloud (a half violin, a box and a group's raw points in one colour) and Horizon (a signed series folded into bands of two hues). Every new call is shown in code on the examples page.

1.21.0 made every chart type and every axes setting come back from JSON as itself. A treemap's, sunburst's, dendrogram's and clustermap's trees, a Sankey's nodes and links, a polar chart's data, a tree grid's rows, a streaming chart's current points and a planar 3-D bar's data all used to come back as a placeholder or a plain series; the MCP server lists and accepts all eight chart types it had refused by name. An axes' Z axis, its 3-D pane colours and its tooltip switch now travel through JSON too. The one series this release does not reach is MatPlotLibNet.Geo's GeoPolygonSeries, whose projection needs a wire shape of its own first. Every fix is shown in code on the examples page.

1.20.0 gave fifteen charts that took a page of code one call each on the axes builder: Pareto, Ridgeline, CalendarHeatmap, QQPlot, ControlChart, KaplanMeier, StreamGraph, Marimekko, Spy and six more take the data as you hold it (names, groups, samples, dates, a matrix) and build the chart from the series the library already has. Underneath them, a figure written to JSON came back as the picture it was, its theme and a colour map built in code included, so the MCP server and every transport carry it whole. NaN is the one missing value: a line breaks at a gap, as in matplotlib, and nothing is drawn at NaN. Bars on a log axis reach the bottom edge, horizontal bars lie along their values, a waterfall marks its totals, and WithDpi and SaveOptions reach the file. Its calls are shown in code on the examples page.

1.19.0 let a line carry its name at its end, in its own colour, instead of in the legend (WithDirectLabel()), and SetYAxisColor / SetXAxisColor colour an axis to match its line in one call, on the left, bottom, right and top axis alike. The right-hand and top axes take their own tick settings, get room of their own in the layout and keep their colours through JSON, and a line on them hides when its legend entry is clicked and reports values in its own axis' units when the line itself is clicked. Its calls are on the examples page.

1.18.2 made a state timeline answer the pointer: hovering a segment names the event and the stretch it covers, clicking it tells your application which segment it was, and a reference line can be moved after it is drawn, which is what a playback marker needs. Dragging now pans a chart that scales itself, which did nothing until the first zoom; a timeline pans and zooms along time only; and stacked charts that share an X axis move together. The WPF chart control also keeps panning and zooming the figure it was last handed, where before it went on acting on the first one, and the package says which Windows version a project has to target to use it. There is a complete WPF example of a replay timeline.

NuGet · Changelog · License: MIT

dotnet add package MatPlotLibNet
using MatPlotLibNet;

double[] x = [1, 2, 3, 4, 5];
double[] y = [2, 4, 3, 5, 1];

Plt.Create()
   .AddSubPlot(1, 1, 1, ax => ax.Plot(x, y, s => s.Label = "signal"))
   .Save("chart.svg");

Start here

Page For
Getting Started install, first chart, output formats, subplots
Fluent Cheatsheet one page: Plt · FigureBuilder · AxesBuilder
Examples what each release added, in code that compiles
Chart Types all 83 series with code — including the control room and the charts in one call
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 what is done and what is still to come, how to help

Also: Playground · From matplotlib to C# · Cookbook · API Reference.

Who it is for

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, no WebView: the WPF, Avalonia and Uno controls draw through SkiaSharp and pan, zoom and brush-select; the MAUI view draws through Microsoft.Maui.Graphics and has no gestures
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

What it is not

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.

Quality bar

Every class passes a strict per-class coverage gate of at least 90 % line and branch coverage. That is currently 810 classes at 99.7 % line and 98.6 % branch coverage, across 19,557 tests. A separate fidelity suite compares rendering with images drawn by matplotlib; it is run by hand, not by CI.

If you have a question or something is missing, open a Discussion or an Issue. Releases follow what people actually need.

Clone this wiki locally