Decision Boundary Viz
Tiles the plot area with a resolution × resolution grid; each cell is colored by the classifier's prediction at its center. Training points are overlaid by their ground-truth label so misclassifications — dot color disagreeing with the surrounding tile — pop out.
Decision boundary plot, 60 by 60 background grid, 24 training samples. Classifier accuracy on training data: 41.7%.
Customize
Classifier
linear
0.00
Grid
60
Display
Installation
npx shadcn@latest add https://craftbits.dev/r/decision-boundary-viz.jsonUsage
import { DecisionBoundaryViz } from "@craft-bits/core";
<DecisionBoundaryViz
predict={(x, y) => (y > 0.5 ? 0 : 1)}
samples={[
{ x: 0.2, y: 0.8, label: 0 },
{ x: 0.8, y: 0.2, label: 1 },
]}
/>Plot a classifier that lives outside the unit square:
<DecisionBoundaryViz
predict={(x, y) => (x * x + y * y < 4 ? 1 : 0)}
samples={samples}
xRange={[-3, 3]}
yRange={[-3, 3]}
/>Trade smoothness for performance with resolution:
<DecisionBoundaryViz
predict={costlyModel.predict}
samples={samples}
resolution={30} /* ~4x fewer predict() calls than the 60 default */
/>Understanding the component
- Predict-as-prop. The component is classifier-agnostic — pass any
(x, y) => 0 | 1function. Logistic regression, k-NN, a decision tree, a tiny MLP: as long as it returns a label, the boundary appears. - Centre-sampled grid. The plot area is sliced into
resolution²cells.predictis called once per cell at its centre, not its corner, so the visible boundary lands on cell edges. Higherresolution= smoother boundary, butpredictruns more times per render — memoize expensive predictors withuseCallback. - Two-colour decision regions. Label
1cells fill withcb-accentat 22% opacity; label0cells fill withcb-fg-muted. The low alpha keeps overlaid scatter points readable. - Sample overlay. Each training point renders as a
4.5pxfilled circle, colored by its ground-truthlabel. A dot whose colour matches the surrounding tile is correctly classified; a colour mismatch is a misclassification — the eye spots it instantly. - Configurable coordinate space.
xRange/yRangedefine the math-space window. The default[0, 1]square fits unit-cube datasets; pass any other domain to scale the plot. - Reduced motion.
prefers-reduced-motion: reduceshort-circuits the background fade-in to an instant swap.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
predict | (x: number, y: number) => 0 | 1 | required | Classifier prediction function. Called resolution² times per render. |
samples | readonly DecisionBoundarySample[] | required | Training points to overlay on top of the background. |
xRange | readonly [number, number] | [0, 1] | Visible x-axis math range. |
yRange | readonly [number, number] | [0, 1] | Visible y-axis math range. |
resolution | number | 60 | Grid resolution — boundary is sampled at resolution × resolution cells. |
showSamples | boolean | true | Render the training-point scatter overlay. |
showAxes | boolean | true | Render the x / y axis tick labels. |
transition | Transition | SPRINGS.smooth | Spring for the background fade-in. |
className | string | — | Merged onto the root via cn(). |
The DecisionBoundarySample shape:
interface DecisionBoundarySample {
x: number; // feature 1 coordinate
y: number; // feature 2 coordinate
label: 0 | 1; // ground-truth class
}Accessibility
- The root is
role="figure"with a visually hidden summary covering the grid resolution, sample count, and the classifier's accuracy on the training set — screen readers hear the gist without needing colour vision. - The decision-region cells and the scatter overlay are marked
aria-hiddenbecause the summary already conveys their information. - Motion respects
prefers-reduced-motion: reduce— the background fade collapses to an instant swap.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/viz/DecisionBoundaryViz.tsx). The source paired a draggable decision-tree grower with an info-gain candidate panel and three lesson modes (Explore / Predict / Challenge). The library extract is the bare decision-boundary primitive — apredictfunction and asamplesarray in, a tinted grid plus scatter out.