-
Notifications
You must be signed in to change notification settings - Fork 2
Fluent Cheatsheet
One-page reference for MatPlotLibNet's fluent builder API. Every chart starts at Plt.Create() and ends at an output call (ToSvg, Save, …). In between, you chain figure-level methods on FigureBuilder and per-subplot methods on AxesBuilder via AddSubPlot(..., ax => ax.Plot(...)).
| Call | Returns | Purpose |
|---|---|---|
Plt.Create() |
FigureBuilder |
The normal entry point. Start fluent construction. |
Plt.Figure(width, height) |
Figure |
Direct model (skip the builder). Rarely used. |
Plt.Mosaic("AB;CC", ...) |
MosaicFigureBuilder |
Subplot layout from an ASCII-art string. |
Plt.Style.Use(...) |
void | Apply a global stylesheet (e.g. "seaborn"). |
Plt.Style.Context(...) |
StyleContext |
Scoped style override (using block). |
Plt.Create()
.WithSize(900, 600) // px — intrinsic / viewBox size
.WithDpi(150) // raster export resolution
.WithTitle("Q1 Report")
.WithTheme(Theme.MatplotlibV2) // or MatplotlibClassic, HighContrast, ColorBlindSafe
.WithBackground(Colors.White)
.WithAltText("Accessible description")
.WithResponsiveSvg(false) // opt out of v1.7.2 Phase L default (max-width:100%;height:auto).AddSubPlot(1, 1, 1, ax => ax.Plot(x, y)) // classic: rows, cols, 1-based index
.AddSubPlot(new GridPosition(0, 1, 0, 2), ax => ...) // GridSpec-based
.WithGridSpec(3, 2, heightRatios: [2, 1, 1]) // uneven row heights.TightLayout() // auto-compute margins from measured text
.ConstrainedLayout() // same idea, more aggressive
.WithSubPlotSpacing(s => s with { MarginTop = 60 }) // manual override.WithZoomPan() // drag-to-pan, wheel-to-zoom
.WithLegendToggle() // click a legend entry → hide/show series
.WithRichTooltips() // hover a point → tooltip
.WithHighlight() // hover a series → dim others
.WithSelection() // click to select points
.With3DRotation() // drag a 3D plot to rotate
.WithTreemapDrilldown() // every depth visible by default; click a parent rect to collapse its entire subtree, click again to restore (v1.7.2 Phase W "steady pictures")
.WithSankeyHover() // hover a Sankey node → isolate reachable flow chain.ToSvg() // string
.Save("chart.svg") // .svg / .png / .pdf / .gif picked from extension
.SaveSvgAndPng("chart") // both at once
.ToJson(indented: true) // serialize the figure
.Build() // Figure model (skip rendering)var handle = await figure.ShowAsync(); // opens a self-hosted browser popup
await handle.UpdateAsync(newFigure); // push a new figure versionThere is no synchronous Show() — InteractiveExtensions.Show(Figure) was removed in v1.13.0
in favor of the async-only surface above. Calling anything on the handle after it is disposed
throws ObjectDisposedException.
Useful for single-plot figures:
Plt.Create().Plot(x, y).Save("line.svg");
Plt.Create().Bar(cats, vals).Save("bar.png");
Plt.Create().Scatter(x, y).Save("scatter.pdf");Supported families at figure level: Plot / Scatter / Bar / Hist / Pie / Image / Heatmap / Treemap / Sunburst / Sankey / Surface / Scatter3D / Bar3D / PolarPlot / Candlestick / OhlcBar / BoxPlot / Violin / many more.
ax.WithTitle("Revenue")
.SetXLabel("Quarter")
.SetYLabel("USD")
.SetZLabel("Units") // 3D only
.SetXLim(0, 10)
.SetYLim(0, 100)
.SetXScale(AxisScale.Log) // log, linear, symlogax.SetXTickLocator(new MaxNLocator(5))
.SetYTickLocator(new AutoLocator())
.SetXTickFormatter(new PercentTickFormatter())
.WithMinorTicks()
.WithYTicksMirrored() // ticks on both left AND right (v1.4.1)
.WithXTicksMirrored() // ticks on both top AND bottom (v1.4.1)
.WithTightMargins() // SetXMargin(0).SetYMargin(0) — data touches spines (v1.4.1, v1.7.2 Phase L.11 also skips nice-bounds expansion)
.WithXTickLabelRotation(30) // rotate X-tick labels (v1.7.2 Phase L.8); auto-30° when labels would overlap
.WithYTickLabelRotation(45) // rotate Y-tick labels (v1.7.2 Phase L.8)
.SetXDateAxis() // interprets X as DateTime
.SetXDateFormat("yyyy-MM")ax.HideTopSpine()
.HideRightSpine()
.HideAllAxes() // Sankey / Treemap canvas (no spines, no ticks, no labels)
.WithSpines(s => s with { Left = s.Left with { LineWidth = 2 } })ax.WithLegend(LegendPosition.UpperRight)
.WithLegend(l => l with { Position = LegendPosition.OutsideRight, NCols = 2, Title = "Series" })
.WithLegendValues() // appends each XY series' last Y value to its legend entry
.ShowGrid()
.WithGrid(g => g with { Color = Colors.LightGray, LineStyle = LineStyle.Dashed })Legend positions: 11 inside (UpperRight, UpperLeft, LowerRight, LowerLeft, Right, CenterLeft, CenterRight, LowerCenter, UpperCenter, Center, Best) + 4 outside (OutsideRight, OutsideLeft, OutsideTop, OutsideBottom — reserved by constrained layout).
Order-independent WithLegend (v1.13.0 fix): WithLegend(position, visible) used to wholesale-replace the Legend record, silently dropping any earlier WithLegendValues() / WithLegend(configure) call. It now only updates Visible and Position, preserving every other property regardless of call order — .WithLegendValues().WithLegend(LegendPosition.UpperRight) and .WithLegend(LegendPosition.UpperRight).WithLegendValues() are equivalent.
LegendValues last-value suffix: WithLegendValues(enabled: true) appends each labelled XYSeries' last data value to its legend entry (e.g. Signal → Signal = 2.70, invariant culture F2). Non-XY series display the label text only. Default false — byte-identical legend output when unused.
ax.AddInset(new InsetBounds(0.55, 0.55, 0.4, 0.4), inset => inset
.Plot(zoomX, zoomY)
.SetXLim(2, 4));
// convenience overload — forwards to the InsetBounds overload above (canonical form, v1.13.0)
ax.AddInset(x: 0.55, y: 0.55, width: 0.4, height: 0.4, inset => inset.Plot(zoomX, zoomY));InsetBounds(X, Y, Width, Height) is a readonly record struct expressed as fractions (0-1) of
the parent axes. AddInset(InsetBounds, configure) is the canonical overload; the double-argument
convenience overload just constructs an InsetBounds and forwards.
ax.ShareX("time-axis")
.WithSecondaryYAxis(y2 => y2.Bar(cats, volume).SetYLabel("Volume"))ax.WithColorMap("viridis") // or ColorMaps.Viridis
.WithColorBar(cb => cb.Label = "Density")
.WithNormalizer(new LogNormalizer(vmin: 1, vmax: 1000))ax.WithYBreak(20, 80, BreakStyle.Zigzag)Every series method takes a final optional Action<T> configure to tweak properties.
| Family | Methods |
|---|---|
| XY line/scatter |
Plot(x, y), Scatter(x, y), ErrorBar(x, y, yErrLow, yErrHi), Step(x, y), FillBetween(x, y, y2), StackPlot(x, ySets)
|
| Signal / realtime |
SignalXY(x, y) (monotonic X, fast), Signal(y, sampleRate, xStart) (sample-rate + offset) |
| Categorical |
Bar(cats, vals), BrokenBarH(ranges), Gantt(tasks, starts, ends), Waterfall(cats, vals), Eventplot(positions), Countplot(values)
|
| Distribution |
Hist(data, bins), BoxPlot(datasets), Violin(datasets), Kde(data), Ecdf(data), Rugplot(data), Stripplot(datasets), Swarmplot(datasets)
|
| 2D grid |
Heatmap(data), Image(data), Pcolormesh(x, y, c), Histogram2D(x, y, bins), Contour(x, y, z), Contourf(x, y, z), Hexbin(x, y), Tricontour(x, y, z), Tripcolor(x, y, z)
|
| Circular |
Pie(sizes, labels), Donut(sizes, labels)
|
| Hierarchical |
Treemap(root), Sunburst(root), NestedPie(root) — all take TreeNode root
|
| Flow |
Sankey(nodes, links) with SankeyNode[] and SankeyLink[]
|
| Polar |
PolarPlot(r, θ), PolarScatter(r, θ), PolarBar(r, θ), PolarHeatmap(data, θBins, rBins), Radar(cats, vals)
|
| Financial |
Candlestick(open, high, low, close, dates?), OhlcBar(open, high, low, close, dates?)
|
| Pair-selection |
RelativeRotation(assetCloses, benchmarkCloses, labels) — RRG: RS-Ratio × RS-Momentum 2D scatter with fading tail |
| 3D |
Surface(x, y, z), Wireframe(x, y, z), Scatter3D(x, y, z), Stem3D(x, y, z), Bar3D(x, y, z), PlanarBar3D(x, y, z)
|
| Field |
Quiver(x, y, u, v), Streamplot(x, y, u, v), Barbs(x, y, speed, dir), QuiverKey(x, y, u, label)
|
| Special |
Gauge(value), ProgressBar(value), Sparkline(values), Bubble(x, y, sizes), Funnel(labels, values), Regression(x, y), Residplot(x, y), Pointplot(datasets), Spectrogram(signal), Table(cellData)
|
The configure callback runs against the concrete series instance, so IntelliSense shows everything. Representative sets:
// Line
ax.Plot(x, y, s =>
{
s.Color = Colors.DodgerBlue;
s.LineWidth = 2.0;
s.LineStyle = LineStyle.Dashed;
s.Marker = MarkerStyle.Circle; // all 13 shapes supported (v1.7.2 Phase M):
// Circle, Square, Triangle, TriangleDown/Left/Right,
// Diamond, Pentagon, Hexagon, Star, Cross, Plus, None
s.MarkerSize = 6;
s.Smooth = true; // cubic-spline smoothing
s.Label = "Revenue"; // for legend
});
// Scatter
ax.Scatter(x, y, s =>
{
s.Sizes = bubbleSizes; // per-point size
s.C = density; // per-point colormap value
s.ColorMap = ColorMaps.Viridis;
s.Alpha = 0.6;
});
// Bar
ax.Bar(cats, vals, s =>
{
s.Color = Colors.SteelBlue;
s.BarWidth = 0.7;
s.ShowLabels = true;
s.LabelFormat = "0.0";
s.EdgeColor = Colors.Black;
s.Orientation = BarOrientation.Horizontal;
});
// Pie
ax.Pie(sizes, labels, s =>
{
s.Explode = [0, 0.1, 0, 0];
s.AutoPct = "{0:F1}%";
s.StartAngle = 90;
s.Shadow = true;
});
// Heatmap / contour / surface
ax.Heatmap(data, s =>
{
s.ColorMap = ColorMaps.Plasma;
s.Normalizer = new LogNormalizer(1, 1000);
});
// Sankey
ax.Sankey(nodes, links, s =>
{
s.NodeWidth = 24;
s.NodePadding = 14;
s.Iterations = 20; // vertical-relaxation passes
s.LinkColorMode = SankeyLinkColorMode.Gradient;
s.InsideLabels = true; // when NodeWidth is wide enough
});After plotting Candlestick / OhlcBar / a price line, add:
ax.Candlestick(open, high, low, close)
.Sma(20)
.Ema(50, s => s.Color = Colors.Orange)
.BollingerBands(period: 20, stdDev: 2.0)
.Rsi(close, 14)
.WilliamsR(high, low, close)
.Obv(close, volume)
.Cci(high, low, close, 20)
.ParabolicSar(high, low);Generic: ax.Indicator(new MyIndicator(...)).
ax.Annotate("Peak", x: 5.0, y: 12.3);
ax.Annotate("Crash", 6.0, 8.0, arrowX: 7.0, arrowY: 9.5);
ax.AxHLine(0); // horizontal reference line
ax.AxVLine(Math.PI, c => c.Color = Colors.Red);
ax.AxHSpan(40, 60); // shaded horizontal band
ax.AxVSpan(DateTime.UtcNow.AddDays(-7), DateTime.UtcNow);
ax.BuyAt(x, y); // trading signal marker
ax.SellAt(x, y);
// Threshold — dashed reference line + shaded breach span + optional label, one call
ax.Threshold(80.0, Orientation.Horizontal, ThresholdBreach.Above,
color: Colors.Red, label: "Alarm");Threshold(value, orientation, breach, color?, label?) composes an AxHLine/AxVLine at
value with a SpanRegion covering the breach zone (ThresholdBreach.Above/Below, extending
to the axis bound) plus an optional label Annotation — no new series or renderer, just the
existing primitives wired together.
Plt.Create()
.WithSize(800, 600)
.With3DRotation() // drag-to-rotate in SVG
.AddSubPlot(1, 1, 1, ax => ax
.Surface(xs, ys, zs, s => s.ColorMap = ColorMaps.Viridis)
.WithCamera(elevation: 35, azimuth: -45, distance: 10)
.WithLighting(dx: 0.3, dy: 0.3, dz: 1.0, ambient: 0.3, diffuse: 0.7)
.SetZLabel("Altitude"))
.Save("surface.svg");distance controls camera distance for the perspective matrix — lower values produce more foreshortening.
Line plot
Plt.Create().Plot(x, y).Save("line.svg");Multi-panel dashboard
Plt.Create()
.WithSize(1200, 800)
.WithGridSpec(2, 2, heightRatios: [3, 1])
.WithTitle("Q1 — ACME")
.TightLayout()
.AddSubPlot(1, 1, 1, ax => ax.Candlestick(o, h, l, c).Sma(20).BollingerBands(20, 2))
.AddSubPlot(1, 1, 2, ax => ax.Bar(dates, volume).SetYLabel("Vol"))
.AddSubPlot(1, 1, 3, ax => ax.Plot(dates, rsi).AxHLine(70).AxHLine(30))
.Save("dashboard.svg");Interactive Sankey
Plt.Create()
.WithSize(1000, 600)
.WithSankeyHover()
.AddSubPlot(1, 1, 1, ax => ax
.HideAllAxes()
.Sankey(nodes, links, s =>
{
s.Iterations = 20;
s.LinkColorMode = SankeyLinkColorMode.Gradient;
}))
.Save("flow.svg");Nested pie
Plt.Create()
.WithTitle("Revenue by department → product")
.AddSubPlot(1, 1, 1, ax => ax.NestedPie(departments))
.Save("nested.svg");- Getting Started — installation & first chart
- Chart Types — all 74 series types with examples
-
Styling — themes, colormaps,
PropCycler -
Matplotlib Themes —
MatplotlibClassicvsMatplotlibV2 - Advanced — date axes, math text, animations, GIF, real-time
- Accessibility — SVG semantics, keyboard nav, color-blind palette