deepbox/plot
ML Diagnostics, Animation & Interactive
Plots for model evaluation, SVG animation, and standalone interactive HTML plots.
- Diagnostics
- Interactive
Overview
- The diagnostic functions take values you already have from
deepbox/metricsanddeepbox/ml.plotConfusionMatrix(cm, labels)takesconfusionMatrixoutput,plotRocCurve(fpr, tpr, auc?)takesrocCurveoutput, andplotCalibrationCurve(fractionPositive, meanPredicted)takes the arrays thatcalibrationCurvereturns, wrapped in tensors.plotFeatureImportance(importances, names)draws bars. plotLearningCurveandplotValidationCurveaccept a 1-D score tensor or an[nPoints, nFolds]matrix, which they average over the folds.Animationrenders a frame generator,(frameIndex, totalFrames, progress) => Figure, to SVG frames or to one animated SVG. Options arefps(30),durationin milliseconds (1000),loopandeasing. There is no video encoder.createInteractivePlot(figure, options)renders a standalone HTML page with pan, zoom, tooltips and reset, and no external scripts. Tooltip points are positioned in figure pixels. You write the HTML to a file yourself.
AnimationEasing
typeNames accepted by AnimationOptions.easing.
type AnimationEasing = "linear" | "ease-in" | "ease-out" | "ease-in-out";AnimationFrame
typeA single animation frame.
readonly index: numberFrame index (0-based).
readonly timeMs: numberTimestamp in milliseconds from the start.
readonly svg: RenderedSVGThe rendered SVG for this frame.
AnimationFrameGenerator
typeFunction that builds the figure for one frame.
- frameIndex is the 0-based frame number. - totalFrames is the number of frames in the animation. - progress is the animation position in [0, 1] after easing. For a looping animation it is frameIndex / totalFrames (the end state is the start state of the next cycle); for a non-looping animation the last frame reaches exactly 1.
type AnimationFrameGenerator = (frameIndex: number, totalFrames: number, progress: number) => Figure;AnimationOptions
typeOptions for creating an animation.
readonly fps?: numberFrames per second, between 1 and 120.
readonly duration?: numberTotal duration in milliseconds (at least 1).
readonly loop?: booleanWhether the animation should loop.
readonly easing?: AnimationEasingEasing applied to the
progressargument passed to the frame generator.
AnimationResult
typeResult of rendering an animation.
readonly frameCount: numberTotal number of frames.
readonly fps: numberFrames per second.
readonly durationMs: numberRequested duration in milliseconds.
readonly loop: booleanWhether the animation loops.
readonly frames: readonly AnimationFrame[]Individual frames.
InteractiveOptions
typeOptions for interactive plot rendering.
readonly pan?: booleanEnable pan interaction.
readonly zoom?: booleanEnable zoom interaction.
readonly tooltips?: booleanEnable tooltips on hover.
readonly crosshair?: booleanEnable crosshair cursor.
readonly resetOnDoubleClick?: booleanEnable reset on double-click.
readonly minZoom?: numberMinimum zoom level (finite and positive).
readonly maxZoom?: numberMaximum zoom level (finite and at least
minZoom).readonly customCSS?: stringCustom CSS to inject into the page's
<style>element.readonly title?: stringHTML page title.
InteractiveResult
typeResult of rendering an interactive plot.
readonly html: stringThe complete HTML document string.
readonly svg: stringThe SVG content embedded in the HTML.
readonly options: Required<Omit<InteractiveOptions, "customCSS" | "title">>Options used for rendering.
TooltipDataPoint
typeData point for tooltip display.
x and y are positions in the rendered SVG, in pixels measured from the top-left corner of the figure (the same units as the figure's width and height). They are not data-space coordinates of the axes.
readonly x: numberHorizontal position in figure pixels (finite).
readonly y: numberVertical position in figure pixels, measured downwards (finite).
readonly label?: stringText shown in the tooltip.
readonly series?: stringSeries name, shown before the label.
Animation
Frame-based animation controller for Deepbox plots.
Create an animation by registering a frame generator function that builds a figure for each frame. The animation then renders all frames and can export them in various formats.
import { Animation, Figure } from 'deepbox/plot';import { tensor } from 'deepbox/ndarray'; const anim = new Animation({ fps: 24, duration: 2000 }); anim.animate((frameIndex, totalFrames, progress) => { const fig = new Figure({ width: 400, height: 300 }); const ax = fig.addAxes(); ax.plot(tensor([0, 0.5, 1]), tensor([0, Math.sin(progress * Math.PI * 2), 0])); return fig;}); const result = anim.render();console.log(result.frameCount); // 48 frames (24fps × 2s) // Export as animated SVGconst svg = anim.toAnimatedSVG();Members (7)
constructor(options?: AnimationOptions)animate(generator: AnimationFrameGenerator): voidRegister a frame generator function.
render(): AnimationResultRender all frames of the animation.
getFrame(index: number): AnimationFrame | undefinedGet a specific rendered frame.
toAnimatedSVG(): stringExport the animation as a single animated SVG.
toFrames(): string[]Export individual frame SVGs.
info(): { fps: number; durationMs: number; totalFrames: number; loop: boolean; easing: AnimationEasing; }Get animation metadata without frame data.
InteractivePlot
Interactive plot wrapper for Deepbox figures.
Wraps a static SVG plot in an HTML document with embedded JavaScript that provides pan, zoom, tooltip, and crosshair interactions.
Tooltip points are positioned in figure pixels (see TooltipDataPoint), so they must be given in the SVG's own coordinate system.
import { InteractivePlot, figure, gca } from 'deepbox/plot';import { tensor } from 'deepbox/ndarray'; // figure() makes the new figure current and gives it one axes.const fig = figure({ width: 800, height: 600 });gca().plot(tensor([1, 2, 3, 4]), tensor([10, 20, 15, 25])); const interactive = new InteractivePlot(fig, { tooltips: true, crosshair: true, zoom: true, pan: true,}); // Tooltip points, in pixels from the top-left corner of the figureinteractive.addDataPoints([ { x: 120, y: 340, label: "Point A" }, { x: 260, y: 210, label: "Point B" },]); const result = interactive.render();// Write result.html to a file and open in a browserMembers (5)
constructor(fig: Figure, options?: InteractiveOptions)addDataPoints(points: readonly TooltipDataPoint[]): voidAdd data points for tooltip display.
getDataPoints(): readonly TooltipDataPoint[]Get a copy of the registered tooltip data points.
clearDataPoints(): voidClear all registered data points.
render(): InteractiveResultRender the interactive plot as a standalone HTML document.
plotConfusionMatrix
function plotConfusionMatrix(cm: Tensor, labels?: readonly string[], options?: PlotOptions): void;Plot a confusion matrix as a heatmap.
Rows are the actual classes and columns the predicted classes. Class 0 is drawn in the top row, matching sklearn.metrics.ConfusionMatrixDisplay. Tick labels default to the class indices.
Parameters
cmTensor- 2D confusion matrix
[n_actual, n_predicted] labelsoptionalreadonly string[]- Optional class names (at least as many as rows and columns)
optionsoptionalPlotOptions- Heatmap options (colormap, vmin, vmax, extent)
Throws
ShapeErrorIfcmis not 2D.InvalidParameterErrorIflabelsis shorter than the matrix.
plotRocCurve
function plotRocCurve(fpr: Tensor, tpr: Tensor, auc?: number, options?: PlotOptions): void;Plot a ROC curve with optional AUC annotation.
Parameters
fprTensor- False positive rates (x axis)
tprTensor- True positive rates (y axis)
aucoptionalnumber- Optional area under the curve, shown in the title
optionsoptionalPlotOptions- Line styling options
plotPrecisionRecallCurve
function plotPrecisionRecallCurve(precision: Tensor, recall: Tensor, averagePrecision?: number, options?: PlotOptions): void;Plot a precision-recall curve with optional AP annotation.
Parameters
precisionTensor- Precision values (y axis)
recallTensor- Recall values (x axis)
averagePrecisionoptionalnumber- Optional average precision, shown in the title
optionsoptionalPlotOptions- Line styling options
plotLearningCurve
function plotLearningCurve(trainSizes: Tensor, trainScores: Tensor, valScores: Tensor, options?: PlotOptions): void;Plot training and validation learning curves.
Scores may be 1D (one value per training size) or 2D [n_sizes, n_folds] as returned by sklearn.model_selection.learning_curve; 2D scores are averaged over the folds.
Parameters
trainSizesTensor- Training set sizes (x axis)
trainScoresTensor- Training scores
valScoresTensor- Validation scores
optionsoptionalPlotOptions- Line options.
colors[0]/colors[1](orcolorfor the training line) set the line colors.
plotValidationCurve
function plotValidationCurve(paramRange: Tensor, trainScores: Tensor, valScores: Tensor, options?: PlotOptions): void;Plot training and validation curves against a hyperparameter range.
Scores may be 1D or 2D [n_values, n_folds] as returned by sklearn.model_selection.validation_curve; 2D scores are averaged over the folds.
Parameters
paramRangeTensor- Hyperparameter values (x axis)
trainScoresTensor- Training scores
valScoresTensor- Validation scores
optionsoptionalPlotOptions- Line options.
colors[0]/colors[1](orcolorfor the training line) set the line colors.
plotDecisionBoundary
function plotDecisionBoundary(X: Tensor, y: Tensor, model: { readonly predict: (x: Tensor) => Tensor; }, options?: PlotOptions): void;Plot a classifier decision boundary on a 2D feature space.
Details
The model is evaluated on a 100 x 100 grid that covers the data range plus a 5% margin. model.predict may return either class labels ([n], or [n, 1]) or per-class scores ([n, k]); with scores, the column index of the largest score is used as the class label, so y must use the labels 0..k-1. Number and bigint labels that are equal (for example 1 and 1n) are treated as the same class.
Parameters
XTensor- Feature matrix of shape
[n, 2]with finite values yTensor- Class labels of shape
[n] model{ readonly predict: (x: Tensor) => Tensor; }- Object with a
predictmethod optionsoptionalPlotOptionscolorsfor the class markers,sizefor the marker size,colormap,vminandvmaxfor the background
Throws
InvalidParameterErrorIfXis not numeric, empty or non-finite, or if the model returns non-numeric scores.ShapeErrorIfX,yor the predictions have the wrong shape.
plotResiduals
function plotResiduals(yTrue: Tensor, yPred: Tensor, options?: PlotOptions): void;Plot residuals (residual against predicted value) for regression diagnostics.
The residual is yTrue - yPred, matching the convention of sklearn.metrics.PredictionErrorDisplay with kind="residual_vs_predicted".
Parameters
yTrueTensor- 1D tensor of observed values
yPredTensor- 1D tensor of predicted values, same length as
yTrue optionsoptionalPlotOptions- Marker styling options
Throws
InvalidParameterErrorIfyTrueis empty.ShapeErrorIf the inputs are not 1D or differ in length.
plotFeatureImportance
function plotFeatureImportance(importances: Tensor, featureNames?: readonly string[], options?: PlotOptions): void;Plot feature importances as a horizontal bar chart.
Features are sorted by importance, with the most important feature at the top.
Parameters
importancesTensor- 1D tensor of finite importance values
featureNamesoptionalreadonly string[]- Optional names, one per feature (default
Feature i) optionsoptionalPlotOptions- Bar styling options
Throws
InvalidParameterErrorIfimportancesis empty or non-finite, orfeatureNamesdoes not have one entry per feature.ShapeErrorIfimportancesis not 1D.
plotElbowCurve
function plotElbowCurve(kValues: Tensor, inertias: Tensor, options?: PlotOptions): void;Plot an elbow curve for KMeans cluster selection.
Parameters
kValuesTensor- Numbers of clusters (x axis)
inertiasTensor- Inertia for each k (y axis)
optionsoptionalPlotOptions- Line styling options
plotSilhouette
function plotSilhouette(kValues: Tensor, silhouetteScores: Tensor, options?: PlotOptions): void;Plot silhouette scores for clustering evaluation.
Parameters
kValuesTensor- Numbers of clusters (x axis)
silhouetteScoresTensor- Mean silhouette score for each k (y axis)
optionsoptionalPlotOptions- Line styling options
plotCalibrationCurve
function plotCalibrationCurve(fractionPositive: Tensor, meanPredicted: Tensor, options?: PlotOptions): void;Plot a calibration curve (reliability diagram).
The argument order follows sklearn.calibration.calibration_curve, which returns (prob_true, prob_pred).
Parameters
fractionPositiveTensor- Fraction of positives in each bin (y axis)
meanPredictedTensor- Mean predicted probability in each bin (x axis)
optionsoptionalPlotOptions- Line styling options
createAnimation
function createAnimation(options?: AnimationOptions): Animation;Create a new Animation instance.
Parameters
optionsoptionalAnimationOptions- Animation options
Returns
AnimationA new Animation
createInteractivePlot
function createInteractivePlot(fig: Figure, options?: InteractiveOptions): InteractivePlot;Create an interactive plot from a Figure.
Parameters
figFigure- The figure to make interactive
optionsoptionalInteractiveOptions- Interactive options
Returns
InteractivePlotA new InteractivePlot instance
import { calibrationCurve } from "deepbox/ml";import { tensor } from "deepbox/ndarray";import { Animation, Figure, createInteractivePlot, figure, plotCalibrationCurve, plotFeatureImportance,} from "deepbox/plot"; const fig = figure({ width: 640, height: 400 });const { fractionPositives, meanPredicted } = calibrationCurve( tensor([0, 0, 1, 1, 1]), tensor([0.1, 0.3, 0.6, 0.8, 0.9]), { nBins: 3 });plotCalibrationCurve(tensor(fractionPositives), tensor(meanPredicted)); figure();plotFeatureImportance(tensor([0.4, 0.35, 0.25]), ["latency", "score", "age"]); const animation = new Animation({ fps: 10, duration: 500 });animation.animate((_index, _total, progress) => { const frame = new Figure({ width: 200, height: 120 }); frame.addAxes().plot(tensor([0, 1]), tensor([0, progress])); return frame;});console.log(animation.render().frameCount); // 5console.log(animation.toAnimatedSVG().length > 0); const page = createInteractivePlot(fig, { tooltips: true }).render();console.log(page.html.startsWith("<!DOCTYPE html>"));Found a mistake? Open an issue.