MatPlotLibNet 0.4.1

dotnet add package MatPlotLibNet --version 0.4.1
                    
NuGet\Install-Package MatPlotLibNet -Version 0.4.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MatPlotLibNet" Version="0.4.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MatPlotLibNet" Version="0.4.1" />
                    
Directory.Packages.props
<PackageReference Include="MatPlotLibNet" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MatPlotLibNet --version 0.4.1
                    
#r "nuget: MatPlotLibNet, 0.4.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MatPlotLibNet@0.4.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MatPlotLibNet&version=0.4.1
                    
Install as a Cake Addin
#tool nuget:?package=MatPlotLibNet&version=0.4.1
                    
Install as a Cake Tool

MatPlotLibNet

A .NET 10 / .NET 8 charting library inspired by matplotlib. Fluent API, dependency injection, parallel SVG rendering, polymorphic export (SVG/PNG/PDF), and multi-platform output to Blazor, MAUI, ASP.NET Core, Angular, React, Vue, and standalone browser popups.

License: GPL v3

Packages

Package Install What it does
MatPlotLibNet dotnet add package MatPlotLibNet Core: models, fluent API, SVG rendering, JSON serialization, transforms
MatPlotLibNet.Skia dotnet add package MatPlotLibNet.Skia PNG and PDF export via SkiaSharp
MatPlotLibNet.Blazor dotnet add package MatPlotLibNet.Blazor MplChart + MplLiveChart Razor components with SignalR
MatPlotLibNet.AspNetCore dotnet add package MatPlotLibNet.AspNetCore REST endpoints, SignalR hub, IChartPublisher
MatPlotLibNet.Maui dotnet add package MatPlotLibNet.Maui Native MplChartView control via Microsoft.Maui.Graphics
MatPlotLibNet.Interactive dotnet add package MatPlotLibNet.Interactive figure.ShowAsync() opens default browser with live updates
MatPlotLibNet.GraphQL dotnet add package MatPlotLibNet.GraphQL GraphQL queries + subscriptions via HotChocolate
@matplotlibnet/angular npm install @matplotlibnet/angular Angular components + TypeScript SignalR client
@matplotlibnet/react npm install @matplotlibnet/react React hooks + components + TypeScript SignalR client
@matplotlibnet/vue npm install @matplotlibnet/vue Vue 3 composables + components + TypeScript SignalR client

Quick start

using MatPlotLibNet;
using MatPlotLibNet.Styling;

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

// Fluent API -> save with format auto-detected from extension
Plt.Create()
    .WithTitle("My Chart")
    .WithTheme(Theme.Seaborn)
    .Plot(x, y, line => { line.Color = Color.Blue; line.Label = "sin(x)"; })
    .Save("chart");  // no extension = SVG by default

// Or get the SVG string directly
string svg = Plt.Create().Plot(x, y).ToSvg();

// Multiple formats — no Build() needed
Plt.Create().Plot(x, y).Save("chart.svg");
Plt.Create().Plot(x, y).Save("chart.png");   // requires MatPlotLibNet.Skia
Plt.Create().Plot(x, y).Save("chart.pdf");   // requires MatPlotLibNet.Skia

Chart types

34 series types with fluent builder API:

Plt.Create()
    .Plot(x, y)                                           // line
    .Scatter(x, y, s => s.MarkerSize = 8)                 // scatter
    .Bar(["Q1", "Q2", "Q3"], [100, 200, 150])             // bar
    .Hist(measurements, bins: 20)                          // histogram
    .Pie([40, 30, 20, 10], ["A", "B", "C", "D"])          // pie
    .Step(x, y, s => s.StepPosition = StepPosition.Post)  // step function
    .FillBetween(x, y)                                    // area / fill between
    .ErrorBar(x, y, errLow, errHigh)                      // error bars
    .Save("chart");

Additional types via AxesBuilder.AddSubPlot: Heatmap, Box, Violin, Contour, Stem, Candlestick, OhlcBar, Quiver, Radar, Donut, Bubble, Waterfall, Funnel, Gantt, Gauge, ProgressBar, Sparkline, Treemap, Sunburst, Sankey, PolarLine, PolarScatter, PolarBar, Surface, Wireframe, Scatter3D.

Stacked bars

.AddSubPlot(1, 1, 1, ax => ax
    .SetBarMode(BarMode.Stacked)
    .Bar(["A", "B"], [10.0, 20.0])
    .Bar(["A", "B"], [5.0, 10.0]))

Annotations and decorations

.AddSubPlot(1, 1, 1, ax => ax
    .Plot(x, y)
    .Annotate("peak", 2.0, 4.0, a => { a.ArrowTargetX = 1.5; a.ArrowTargetY = 3.5; })
    .AxHLine(3.5, l => l.Color = Color.Red)           // horizontal reference line
    .AxVLine(2.0)                                       // vertical reference line
    .AxHSpan(3.0, 4.0, s => s.Alpha = 0.1)            // shaded horizontal region
    .AxVSpan(1.5, 2.5))                                // shaded vertical region

Secondary Y-axis (TwinX)

.AddSubPlot(1, 1, 1, ax => ax
    .Plot(time, temperature)
    .SetYLabel("Temperature (C)")
    .WithSecondaryYAxis(sec => sec
        .SetYLabel("Humidity (%)")
        .Plot(time, humidity, s => s.Color = Color.Orange)))

Technical indicators (TradingView-style)

// Overlay indicators — auto-detect price data from series on axes
ax.Candlestick(open, high, low, close)
  .Sma(20)                           // adds SMA overlay
  .Ema(9)                            // adds EMA overlay
  .BollingerBands(20, 2.0)           // adds BB bands + middle line

// Buy/sell signals
  .BuyAt(5, close[5])
  .SellAt(12, close[12])

// Panel indicators in subplots
.AddSubPlot(3, 1, 2, ax => ax.Rsi(close, 14).AxHLine(70).AxHLine(30))
.AddSubPlot(3, 1, 3, ax => ax.AddIndicator(new Macd(close)))

13 indicators: SMA, EMA, Bollinger Bands, VWAP, RSI, MACD, Stochastic, Volume, Fibonacci, ATR, ADX, Keltner Channels, Ichimoku Cloud.

Trading analytics: EquityCurve, ProfitLoss, DrawDown — for strategy backtesting panels.

Hierarchical charts (Treemap + Sunburst)

var tree = new TreeNode
{
    Label = "Sales",
    Children = [
        new TreeNode { Label = "Electronics", Value = 400 },
        new TreeNode { Label = "Clothing", Value = 300 },
        new TreeNode { Label = "Food", Value = 200 }
    ]
};

Plt.Create().Treemap(tree).Save("treemap");     // nested rectangles
Plt.Create().Sunburst(tree).Save("sunburst");   // concentric ring segments

Sankey diagrams

SankeyNode[] nodes = [new("A"), new("B"), new("C")];
SankeyLink[] links = [new(0, 1, 30), new(0, 2, 20)];

Plt.Create().Sankey(nodes, links).Save("sankey");

Legend

.AddSubPlot(1, 1, 1, ax => ax
    .Plot(x, temp, s => s.Label = "Temperature")
    .Plot(x, humidity, s => s.Label = "Humidity")
    .WithLegend(LegendPosition.UpperRight))

Subplot spacing

Plt.Create()
    .TightLayout()
    .AddSubPlot(2, 2, 1, ax => ax.Plot(x, y))
    .AddSubPlot(2, 2, 2, ax => ax.Scatter(x, y))
    .Save("tight");

// Or custom margins
Plt.Create()
    .WithSubPlotSpacing(s => s with { MarginLeft = 80, HorizontalGap = 20 })
    .Save("custom_spacing");

Polar plots

double[] r = [1, 2, 3, 4, 5];
double[] theta = [0, 0.5, 1.0, 1.5, 2.0];

// Polar line
Plt.Create().PolarPlot(r, theta).ToSvg();

// Polar scatter
Plt.Create().PolarScatter(r, theta).ToSvg();

// Polar bar (windrose-style)
Plt.Create().PolarBar([5, 10, 8, 3], [0, Math.PI/2, Math.PI, 3*Math.PI/2]).ToSvg();

3D plots

double[] x = [0, 1, 2, 3];
double[] y = [0, 1, 2, 3];
double[,] z = { {0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6} };

// Surface plot with color mapping
Plt.Create().Surface(x, y, z).Save("surface");

// Wireframe
Plt.Create().Wireframe(x, y, z).Save("wireframe");

// 3D scatter
Plt.Create().Scatter3D([1, 2, 3], [4, 5, 6], [7, 8, 9]).Save("scatter3d");

// Custom projection angle
Plt.Create()
    .AddSubPlot(1, 1, 1, ax => ax
        .WithProjection(elevation: 45, azimuth: -45)
        .Surface(x, y, z))
    .Save("rotated");

Color bar

Plt.Create()
    .AddSubPlot(1, 1, 1, ax => ax
        .Heatmap(data)
        .WithColorBar(cb => cb with { Label = "Temperature" }))
    .Save("heatmap_colorbar");

Axis formatting

// Date axis
.AddSubPlot(1, 1, 1, ax => ax
    .SetXDateFormat("MMM yyyy")
    .Plot(dates, values))

// Custom tick formatter
.SetXTickFormatter(new LogTickFormatter())

Subplots

Plt.Create()
    .WithSize(1200, 600)
    .AddSubPlot(1, 2, 1, ax => ax
        .WithTitle("Temperature")
        .SetXLabel("Time").SetYLabel("Celsius")
        .Plot(time, temp)
        .ShowGrid())
    .AddSubPlot(1, 2, 2, ax => ax
        .WithTitle("Distribution")
        .Hist(samples, bins: 15))
    .Save("subplots");

Subplots render in parallel -- each gets its own SVG context, merged in order.

Export transforms

All output formats share the IFigureTransform interface with a fluent TransformResult. No .Build() needed:

using MatPlotLibNet.Transforms;

// Auto-detect format from file extension -- no Build() needed
Plt.Create().Plot(x, y).Save("chart.svg");
Plt.Create().Plot(x, y).Save("chart.png");   // requires MatPlotLibNet.Skia
Plt.Create().Plot(x, y).Save("chart.pdf");   // requires MatPlotLibNet.Skia
Plt.Create().Plot(x, y).Save("chart.json");

// Convenience methods
string svg = Plt.Create().Plot(x, y).ToSvg();
string json = Plt.Create().Plot(x, y).ToJson();

// Register PNG/PDF once at startup (when using MatPlotLibNet.Skia)
FigureExtensions.RegisterTransform(".png", new PngTransform());
FigureExtensions.RegisterTransform(".pdf", new PdfTransform());

SVG interactivity

// Native browser tooltips on hover
.AddSubPlot(1, 1, 1, ax => ax.WithTooltips().Scatter(x, y))

// Zoom (mouse wheel) and pan (click-drag) via embedded JavaScript
Plt.Create().WithZoomPan().Plot(x, y).Save("zoomable")

Dependency injection

Rendering and serialization are interface-based:

// ASP.NET Core -- all services registered automatically
builder.Services.AddMatPlotLibNetSignalR();

// Console apps -- static defaults via ChartServices
string svg = ChartServices.SvgRenderer.Render(figure);
string json = ChartServices.Serializer.ToJson(figure);

// Replace with custom implementations
ChartServices.Serializer = new MyCustomSerializer();

Interfaces: IFigureTransform, IChartRenderer, ISvgRenderer, IChartSerializer, IChartPublisher.

Themes

Theme Style
Theme.Default White background, classic matplotlib
Theme.Dark Dark gray, light text
Theme.Seaborn Light gray, statistical
Theme.Ggplot R ggplot2
Theme.Bmh Bayesian Methods
Theme.FiveThirtyEight Journalism

Custom themes with immutable records:

var theme = Theme.CreateFrom(Theme.Dark)
    .WithBackground(Color.FromHex("#1a1a2e"))
    .WithFont(f => f with { Family = "Consolas", Size = 14 })
    .WithGrid(g => g with { Visible = true, Alpha = 0.3 })
    .Build();

Animation

using MatPlotLibNet.Animation;
using MatPlotLibNet.Interactive;

// Legacy: AnimationBuilder for frame-based animation
var animation = new AnimationBuilder(60, frame =>
    Plt.Create()
        .WithTitle($"Frame {frame}")
        .Plot(x, x.Select(v => Math.Sin(v + frame * 0.1)).ToArray())
        .Build());

// Play in browser with 50ms between frames
var handle = await Plt.Create().Plot(x, y).Build().ShowAsync();
await handle.AnimateAsync(animation);

// New: IAnimation<TState> + AnimationController<TState> for typed animation pipelines
// LegacyAnimationAdapter bridges AnimationBuilder to the new IAnimation<TState> contract

Real-time charts

Server (ASP.NET Core):

await publisher.PublishSvgAsync("sensor-1", figure);

Blazor:

<MplLiveChart ChartId="sensor-1" HubUrl="/charts-hub" />

Angular:

<mpl-live-chart [chartId]="'sensor-1'" [hubUrl]="'/charts-hub'"></mpl-live-chart>

React:

<MplLiveChart chartId="sensor-1" hubUrl="/charts-hub" />

Vue:

<MplLiveChart chartId="sensor-1" hubUrl="/charts-hub" />

GraphQL (subscription):

subscription { onChartSvgUpdated(chartId: "sensor-1") }

All platforms use IChartSubscriptionClient -- same SignalR protocol, different implementations (C# / TypeScript).

Interactive browser popup

using MatPlotLibNet.Interactive;

var handle = await figure.ShowAsync();   // opens default browser
await handle.UpdateAsync();              // pushes live updates

Performance: server-side SVG + SignalR

Charts render server-side as SVG and push to clients via SignalR — no client-side chart library, no JavaScript rendering, no canvas redraws.

  • Less traffic — a chart SVG is 5-15 KB vs. shipping raw datasets (100 KB+) plus a JS chart library (200-500 KB). Only changed charts are pushed.
  • Zero client CPU — the browser swaps innerHTML. A Raspberry Pi displays the same dashboard as a workstation.
  • Inline SVG in the DOM — CSS-stylable, printable, accessible to screen readers. Works in hidden tabs and below the fold.
  • Inline, expandable, or popup — view charts in-page, expand in-place, or pop out into a separate window. figure.ShowAsync() opens a standalone browser with live updates.
  • Same output everywhere — identical SVG whether inline in Blazor, pushed to React via SignalR, saved as a file, exported to PNG/PDF, or rendered in MAUI.

A simple line chart: 52 us. A treemap: 26 us. A 3D surface: 72 us. A 3x3 subplot grid: 422 us. All 13 indicators on 100K points: < 8 ms. See BENCHMARKS.md.

Architecture

MatPlotLibNet (Core)                      net10.0 + net8.0
    |
    +-- MatPlotLibNet.Skia                PNG + PDF export via SkiaSharp
    +-- MatPlotLibNet.Blazor              Razor components + C# SignalR client
    +-- MatPlotLibNet.AspNetCore          REST endpoints + SignalR hub
    |       +-- MatPlotLibNet.Interactive  embedded Kestrel + browser popup
    |       +-- MatPlotLibNet.GraphQL      GraphQL queries + subscriptions (HotChocolate)
    +-- MatPlotLibNet.Maui                native GraphicsView rendering
    +-- @matplotlibnet/angular            Angular components + TS SignalR client
    +-- @matplotlibnet/react              React hooks + components + TS SignalR client
    +-- @matplotlibnet/vue                Vue 3 composables + components + TS SignalR client

See ARCHITECTURE.md for the full rendering pipeline, data flow, and design patterns.

Version history

Version Highlights
0.4.0 34 series types (11 families), 798 tests. OO architecture: AxesRenderer polymorphism (CartesianAxesRenderer, PolarAxesRenderer, ThreeDAxesRenderer). ISeriesSerializable on all 34 series, SeriesRegistry for deserialization. Generic bases: XYSeries, PolarSeries, GridSeries3D, HierarchicalSeries. Interfaces: IHasDataRange, IPolarSeries, I3DGridSeries, I3DPointSeries, IPriceSeries. Thread-safe: volatile fields, ConcurrentDictionary for GlobalTransforms, AxesRenderer registry, SeriesRegistry. Animation: IAnimation<TState>, AnimationController<TState>, LegacyAnimationAdapter. Save("chart") API with format auto-detect. FigureBuilder SRP: Save/Transform moved to FigureExtensions. Color constants (Tab10Blue, GridGray, etc.). ITickFormatter pipeline. ColorBar, Legend, SubPlotSpacing. Polar + 3D coordinate systems.
0.3.2 Quality release: OO indicator refactor (Indicator<TResult> with IIndicatorResult constraint, named result records, no statics). 92 new tests. BenchmarkDotNet suite. CHANGELOG, BENCHMARKS.md, DocFX, 4 sample projects. JSON serialization fix for 9 series types.
0.3.1 Platform expansion: @matplotlibnet/react (React 19 hooks + components), @matplotlibnet/vue (Vue 3 composables + components), MatPlotLibNet.GraphQL (HotChocolate queries + subscriptions). Core library multi-targets netstandard2.1.
0.3.0 25 series types (Donut, Bubble, OhlcBar, Waterfall, Funnel, Gantt, Gauge, ProgressBar, Sparkline). 13 technical indicators (SMA, EMA, BB, VWAP, RSI, MACD, Stochastic, Volume, Fibonacci, ATR, ADX, Keltner, Ichimoku). Trading analytics (EquityCurve, ProfitLoss, DrawDown). Buy/sell signal markers. Generic SeriesRenderer<T> + Indicator<TResult>. Intuitive fluent API (.Sma(20), .BuyAt(), .SaveSvg()). PriceSource enum, Offset, LineStyle on all indicators. Series organized by chart family.
0.2.0 16 series types (Area, Step, ErrorBar, Candlestick, Quiver, Radar). Stacked bars. Annotations (text, HLine/VLine, HSpan/VSpan). Secondary Y-axis (TwinX). SVG tooltips + zoom/pan. Polymorphic transforms (IFigureTransform, FigureTransform, TransformResult). PNG/PDF export via MatPlotLibNet.Skia.
0.1.0 Initial release. 10 series types (Line, Scatter, Bar, Histogram, Pie, Heatmap, Box, Violin, Contour, Stem). Fluent builder API. Parallel SVG rendering. JSON serialization. 6 themes. Blazor, ASP.NET Core, MAUI, Angular, Interactive packages.

See CHANGELOG.md for detailed release notes. See BENCHMARKS.md for performance numbers.

License

GPL-3.0 -- Copyright (c) 2026 H.P. Gansevoort

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on MatPlotLibNet:

Package Downloads
MatPlotLibNet.Skia

PNG and PDF export for MatPlotLibNet charts using SkiaSharp.

MatPlotLibNet.AspNetCore

ASP.NET Core endpoint helpers for MatPlotLibNet. Serves chart JSON specs for Angular and other SPA frameworks.

MatPlotLibNet.Blazor

Blazor components for MatPlotLibNet charting library. Renders charts as inline SVG.

MatPlotLibNet.Maui

MAUI controls for MatPlotLibNet charting library. Renders charts via Microsoft.Maui.Graphics.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.1 112 4/6/2026
0.4.0 100 4/6/2026
0.2.0 101 4/5/2026