Interactive SVG
Browser-interactive charts
Add .WithBrowserInteraction() to make SVG output interactive — pan, zoom, tooltips, legend toggle, legend drag, treemap drilldown, sankey hover, 3D rotation, brush selection, highlight — no .NET runtime needed on the client:
Plt.Create()
.WithBrowserInteraction()
.WithTitle("Interactive Chart")
.Plot(x, y, s => s.Label = "Sensor A")
.Scatter(x, y2, s => s.Label = "Sensor B")
.WithLegend()
.Save("interactive.svg");
One switch wires everything.
WithBrowserInteraction()is the only call you need. The library detects which scripts are relevant per chart (legend drag bails when there is no legend; treemap drilldown bails when there are no treemap nodes) and emits only those. There is no per-feature toggle for the user to manage.
Open the SVG in any browser:
- Drag the chart to pan (hold x / y to lock an axis — matplotlib
_base.py:format_deltasparity) - Scroll to zoom (
0.85^stepper wheel notch — matches matplotlibNavigationToolbar2.scroll_handler) - Double-click or Home to reset view
- Arrow keys to nudge pan, +/- for keyboard zoom
- Click legend items to show/hide series (Enter/Space keyboard-equivalent, WCAG 2.1.1 Level A)
- Press-and-hold a legend item, then drag to reposition the legend group anywhere on the chart (release to drop). Translation is client-only — lost on full server re-render. New in v1.7.2 Phase S.
- Hover data points to see tooltips (focus via Tab for keyboard users — tooltip anchors at element bounds)
See the Keyboard Shortcuts wiki page for the complete reference.
Individual interaction toggles
Enable only the interactions you need:
Plt.Create()
.WithZoomPan() // drag to pan, scroll to zoom
.WithRichTooltips() // styled HTML tooltips on hover
.WithLegendToggle() // click legend to hide/show series
.WithHighlight() // dim siblings on series hover
.WithSelection() // Shift+drag rectangular data selection
.Plot(x, y, s => s.Label = "Data")
.WithLegend()
.Save("custom_interactive.svg");
Interactive financial chart
Plt.Create()
.WithBrowserInteraction()
.WithTitle("Stock Price — Hover for OHLC values")
.AddSubPlot(1, 1, 1, ax => ax
.Candlestick(open, high, low, close, dateLabels, s =>
{
s.UpColor = Colors.Green;
s.DownColor = Colors.Red;
})
.SetXDateFormat("yyyy-MM-dd"))
.Save("interactive_financial.svg");
Interactive 3D with rotation
Combine browser interaction with 3D rotation. Drag uses matplotlib's canonical
formula (dazim/delev = -(dx/w or dy/h) × 180 — full-axes drag = 180°). Wheel
zoom works on every 3D chart (Phase F.3 of v1.7.2 removed the need for an
explicit distance:). Labels keep their outside-cube perpendicular offset
under rotation (Phase F.2). Back panes never paint over surface quads — the
depth-sort is scoped to the mpl-3d-data tier group (Phase F).
Plt.Create()
.WithBrowserInteraction()
.With3DRotation() // mouse-drag to rotate the 3D view
.AddSubPlot(1, 1, 1, ax => ax
.WithCamera(elevation: 35, azimuth: -50)
.Surface(x, y, z, s => s.ColorMap = ColorMaps.Viridis))
.Save("interactive_3d.svg");
Keyboard: arrow keys rotate ±5° (az / el), +/- change camera distance by 0.5, Home restores the initial camera state.
Server-authoritative interaction (SignalR)
For bidirectional interactive charts with server-side state:
Plt.Create()
.WithServerInteraction("chart-1", opt =>
{
opt.OnZoom = (chartId, ev) => Console.WriteLine($"Zoomed: {ev}");
opt.OnBrushSelect = (chartId, ev) => Console.WriteLine($"Selected: {ev}");
opt.OnHover = (chartId, ev) => Console.WriteLine($"Hover: {ev}");
})
.Plot(x, y, s => s.Label = "Live Data")
.Save("server_interactive.svg");
How it works
The SVG embeds self-contained JavaScript (no external dependencies):
| Script | What it does |
|---|---|
| Pan/Zoom | Manipulates SVG viewBox on drag/scroll |
| Tooltips | Reads data-x/data-y attributes, shows floating callout |
| Legend Toggle | Toggles display:none on series groups, supports keyboard (Enter/Space) |
| Highlight | Dims sibling series on hover |
| Selection | Shift+drag draws selection rectangle, fires callback |
Responsive sizing (v1.7.2 Phase L)
By default the SVG root carries an inline style="max-width:100%;height:auto" declaration, so the chart scales fluidly with its container while the viewBox preserves aspect ratio. The pixel width / height attributes stay on the element so naturalWidth / naturalHeight — relied on by client-side PNG export paths — continue to report the intrinsic pixel size.
If you need byte-identical pre-v1.7.2 SVG output (e.g. pixel-diff test fixtures), opt out:
Plt.Create()
.WithResponsiveSvg(false) // emits fixed pixel width/height with no inline style
.Plot(x, y)
.Save("fixed.svg");
Static vs Interactive
// Static SVG (default) — smaller file, perfect for PDF/print
Plt.Create().Plot(x, y).Save("static.svg");
// Interactive SVG — larger file, needs browser
Plt.Create().WithBrowserInteraction().Plot(x, y).Save("interactive.svg");
The interaction scripts add ~3KB to the SVG file size.
Fluent API reference
| Method | Description |
|---|---|
.WithBrowserInteraction() |
Enable all client-side interactions (pan, zoom, tooltips, legend toggle, 3D rotate, treemap drilldown, sankey hover) |
.WithZoomPan() |
Drag to pan, scroll to zoom, x/y axis-lock modifiers, keyboard +/-/arrows/Home |
.WithRichTooltips() |
Styled HTML tooltips on hover + focus (ARIA role="tooltip", aria-live="polite") |
.WithLegendToggle() |
Click legend entries (or Enter/Space for keyboard) to toggle series visibility |
.WithHighlight() |
Dim sibling series on hover; opacity themable via WithInteractionTheme; original opacity preserved across hover cycles |
.WithSelection() |
Shift+drag rectangular data selection; Escape cancels without dispatching |
.With3DRotation() |
Drag to rotate (matplotlib parity), arrow keys ±5°, +/- distance, wheel zoom, Home reset |
.WithTreemapDrilldown() |
Every depth visible by default (interactive view = static SVG, "steady pictures"); click a parent rect to collapse its entire subtree (transitive — descendants' own state preserved); click again to restore. Multiple subtrees can be collapsed independently. Z-order paints children over parents so the deepest visible label wins. (v1.7.2 Phase W; was drill-zoom + Esc-pop in v1.x, expand-on-click in Phase P.) |
.WithSankeyHover() |
Node hover emphasises upstream + downstream flow (ECharts focus: adjacency parity), keyboard via Tab |
.WithInteractionTheme(theme) |
Themable opacity / transition tokens (highlight opacity, sankey dim opacities, treemap transition ms, tooltip offset) |
.WithServerInteraction(id, cfg) |
Bidirectional SignalR interaction (hub methods OnZoom / OnPan / OnReset / OnLegendToggle / OnBrushSelect / OnHover) |