@nbimplot/web
v0.1.13
Published
Standalone ImPlot + WASM plotting for fast interactive browser visualizations.
Downloads
560
Maintainers
Readme
@nbimplot/web
Standalone ImPlot + WASM plotting for browser applications.
This package is the direct webapp surface for nbimplot. It does not require
Jupyter, Python, anywidget, or notebook comms at runtime.
Links:
- Demo: https://prinkesh.github.io/nbimplot/
- GitHub: https://github.com/Prinkesh/nbimplot
- PyPI package: https://pypi.org/project/nbimplot/
- LLM summary: https://prinkesh.github.io/nbimplot/llms.txt
- Full LLM docs: https://prinkesh.github.io/nbimplot/llms-full.txt
Install
From this repository before npm publication:
npm install /path/to/nbimplot/packages/webAfter publishing to npm:
npm install @nbimplot/webUsage
import { createPlot } from "@nbimplot/web";
const plot = await createPlot("#plot", {
width: 900,
height: 450,
title: "Signal",
});
const x = new Float32Array(1_000_000);
const y = new Float32Array(x.length);
for (let i = 0; i < y.length; i += 1) {
x[i] = i * 0.001;
y[i] = Math.sin(x[i]);
}
const h = plot.line("mid", y, {
x,
color: "#2563eb",
lineWeight: 2,
});
plot.render();
h.setData(y, { x });
plot.dispose();Runtime Requirements
- Browser with WebGL2.
- Assets must be served over HTTP(S), not opened directly as
file://. - The package ships
wasm/nbimplot_wasm.jsandwasm/nbimplot_wasm.wasm.
Asset Loading
By default, the package loads the colocated .wasm file:
await createPlot("#plot");You can override the WASM binary URL:
await createPlot("#plot", {
wasmUrl: "/static/nbimplot_wasm.wasm",
});You can also pass a pre-fetched binary:
const wasmBinary = new Uint8Array(await (await fetch("/nbimplot_wasm.wasm")).arrayBuffer());
await createPlot("#plot", { wasmBinary });API Surface
Core methods:
createPlot(target, options)createDashboard(target, { rows, cols, linkX, linkY })plot.line(name, y, options)plot.lines(series, options)plot.streamLine(name, { capacity, initial })handle.setData(y, { x })handle.append(y)plot.render()plot.requestRender()/plot.draw()plot.toDataURL(type?, quality?)plot.toBlob(type?, quality?)plot.downloadPNG(filename?)plot.copy_png_to_clipboard()plot.autoscale()plot.setView(xMin, xMax, yMin, yMax)plot.setTheme(name)plot.setLinkedCrosshair(groupId, { axis })plot.getState({ includeData })/plot.setState(state)plot.exportJSONState({ includeData, filename })plot.exportHTML({ title })plot.getView()plot.getPerfStats()plot.dispose()plot.onViewChange(callback)plot.onPerfStats(callback)plot.onHover(callback)plot.onClick(callback)plot.onSelection(callback)/plot.onSelect(callback)plot.onInteraction(callback)for raw 8-float WASM interaction tuplesplot.indicesForSelection(selection, series?)plot.selectionBounds(selection)plot.highlightSelection(selection, series?, options?)plot.exportCSVSelection(selection, series?, options?)
Plot primitives:
scatter,bubbles,stairs,stems,digitalbars,barGroups,barsH,shadederrorBars,errorBarsHinfLines,vlines,hlineshistogram,histogram2d,heatmap,image,pieChartcandlestick,ohlc,quiver,contour,waterfall,spectrogramtext,annotation,dummytagX,tagYcolormapSlider,colormapButton,colormapSelectordragLineX,dragLineY,dragPoint,dragRectprimitive(kind, payload, buffers)for direct access to supported WASM primitive kinds
Python-style aliases are available for common names, such as stream_line,
bar_groups, bars_h, error_bars, heatmap, set_view,
set_subplots_config, set_colormap, export_csv_selection, and
export_json_state.
Search terms this package is designed to answer: ImPlot web plotting, WASM plotting, WebGL2 time-series plotting, typed-array plotting, large-data browser visualization, and million-point interactive line charts.
Typed Data
Use Float32Array for the fastest path:
const y = new Float32Array(10_000_000);
plot.line("large", y);Batch related lines with one API call:
const handles = plot.lines({
mid: { x, y: mid, color: "#1f6f66" },
vwap: { x, y: vwap, color: "#b74b2b" },
});Date inputs become ImPlot time-axis values automatically, and string/category
x values become labeled ticks:
plot.line("latency", latency, { x: dateArray });
plot.scatter("scores", new Float32Array([0.7, 0.9, 0.6]), { x: ["A", "B", "C"] });Interaction Callbacks
plot.onHover((event) => {
console.log(event.seriesName, event.index, event.x, event.y);
});
plot.onClick((event) => {
console.log(event.button, event.x, event.y);
});
plot.onSelection((event) => {
const exact = plot.indicesForSelection(event);
for (const [seriesToken, indices] of exact) {
console.log(seriesToken, indices.length);
}
});Selection events include the ImPlot rectangle plus per-series x-index ranges from
WASM. indicesForSelection(...) computes exact y-filtered indices only when
called.
View, Axis, and Perf Controls
plot.setPlotFlags({ noLegend: false, noMenus: false, noBoxSelect: false, crosshairs: true });
plot.setSecondaryAxes({ x2: true, y2: true });
plot.setTimeAxis("x1");
plot.setAxisState("x2", { enabled: true, scale: "time" });
plot.setAxisLink("x2", "x1");
plot.setAxisLimitsConstraints("y1", -1.4, 1.4);
plot.setAxisZoomConstraints("x1", 300, 10800);
plot.setAlignedGroup("advanced-api", { enabled: true, vertical: true });
plot.onViewChange((view) => console.log(view));
plot.onPerfStats((stats) => console.log(stats.frameMs));
console.log(plot.getView(), plot.getPerfStats());
plot.requestRender();
plot.draw();Theme presets are applied by the WASM/C++ layer:
plot.setTheme("publication");
plot.setTheme("finance");
plot.setTheme("dark-terminal");For explicit x coordinates:
const h = plot.line("large", y, { x });
h.setData(yNew, { x: xNew });x must be finite, equal-length with y, and sorted in non-decreasing order
so the WASM LOD engine can binary-search the visible range. If the line keeps
the same length, h.setData(yNew) preserves the existing x buffer.
Streaming can also carry explicit x chunks:
const h = plot.streamLine("ticks", { capacity: 200_000, initial, x: initialX });
h.append(chunk, { x: chunkX });
h.pause();
h.resume();
h.setWindow(50_000);
h.setStreamOptions({ autoRender: true, autoscaleY: false });
h.clear();PNG Export
await plot.downloadPNG("nbimplot-signal.png");
const dataUrl = plot.toDataURL("image/png");
const blob = await plot.toBlob("image/png");
await plot.copy_png_to_clipboard();The export methods redraw the current strict WASM/ImPlot canvas immediately before reading pixels. They do not use a JavaScript renderer fallback.
For standalone HTML state export:
const html = plot.exportHTML({ title: "Signal Export" });
const same = plot.export_html({ title: "Signal Export" });The exported page reloads @nbimplot/web and renders through WASM/ImPlot.
For heatmap, pass a flat Float32Array plus shape:
plot.heatmap("z", z, {
rows: 256,
cols: 512,
labelFmt: "",
showColorbar: true,
});For image, pass flat grayscale/RGB/RGBA float data:
plot.image("img", pixels, {
rows: 512,
cols: 512,
channels: 4,
});Specialty scientific and financial methods are also available:
plot.candlestick("candles", open, high, low, close, { x, width: 0.7 });
plot.ohlc("ohlc", open, high, low, close, { x, width: 0.35 });
plot.quiver("field", x, y, u, v, { scale: 0.08, normalize: true });
plot.contour("contours", z, { rows, cols, levels, bounds: [[-3, -3], [3, 3]] });
plot.waterfall("waterfall", z, { rows, cols, scale: 0.18 });
plot.spectrogram("spectrogram", z, { rows, cols, labelFmt: "", showColorbar: true });Interactions
ImPlot handles the interaction model:
- drag pan
- wheel zoom
- right-click context menu
- right-drag box zoom
- double-click autoscale
- legend toggles
Example
Run the plain browser example from the repository root:
python3 -m http.server 8000Then open:
http://localhost:8000/packages/web/examples/plain/