Norm Distribution Viz

Plot a Gaussian N(μ, σ²) as a smooth bell curve with shaded ±1σ and ±2σ regions. Two sliders drive μ and σ; the curve translates and stretches in place inside a stable x-axis. Useful for teaching the geometry of the normal distribution, the 68-95-99.7 rule, or the effect of parameter changes on a probability density.

Normal distribution visualizationNormal distribution N(0.00, 1.00). Mean 0.00, standard deviation 1.00. Plotted over x in [-15.00, 15.00].
μ = 0.00σ = 1.00σ² = 1.00
-15.00-7.500.007.5015.00
0.00
1.00
Customize
Parameters
0
1
Display

Installation

npx shadcn@latest add https://craftbits.dev/r/norm-distribution-viz.json

Usage

import { NormDistributionViz } from "@craft-bits/core";
 
<NormDistributionViz defaultMean={0} defaultStddev={1} />

Control μ and σ from outside the component:

const [mu, setMu] = useState(0);
const [sigma, setSigma] = useState(1);
 
<NormDistributionViz
  mean={mu}
  onMeanChange={setMu}
  stddev={sigma}
  onStddevChange={setSigma}
/>

Pin the x-axis and hide the shaded regions:

<NormDistributionViz
  defaultMean={0}
  defaultStddev={1}
  xRange={[-5, 5]}
  showSigmaRegions={false}
/>

Understanding the component

  1. Bell curve from analytic parameters. The component samples the Gaussian PDF f(x | μ, σ) = exp(−(x − μ)² / 2σ²) / (σ · √(2π)) at 120 evenly-spaced x-values and rasterizes the result as one SVG path. No samples, no smoothing, no histogramming — the curve is the analytic density.
  2. Shaded ±σ regions. When showSigmaRegions is on, two filled regions sit under the curve: the inner ±1σ band at 30% accent opacity (~68% of probability mass), and the outer ±2σ band at 15% accent opacity (~95% of mass). The ±2σ band is drawn first so the ±1σ band visually deepens on top of it.
  3. Stable x-axis. Unless xRange is supplied, the plot uses a fixed window of [meanMin − 4·sigmaMax, meanMax + 4·sigmaMax]. It stays put as the sliders move, so the user sees the curve translate and stretch inside the same frame instead of the axis re-fitting under them.
  4. Auto-normalized y-axis. The y-scale is normalized to the current peak density 1 / (σ√(2π)). Sharpening σ makes the curve taller; flattening σ makes it shorter. Visual height encodes density, not raw mass.
  5. Controlled and uncontrolled, twice. Both mean and stddev pair a controlled value + onChange with an uncontrolled default*. Out-of-range values clamp on read.
  6. Spring transitions. The bell d, the two shaded region paths, and the mean guideline all animate with SPRINGS.smooth. prefers-reduced-motion: reduce collapses every spring to duration: 0.

Props

PropTypeDefaultDescription
meannumberControlled mean μ. Pair with onMeanChange.
defaultMeannumber0Uncontrolled initial mean.
onMeanChange(mean: number) => voidFires on every μ commit.
stddevnumberControlled standard deviation σ. Pair with onStddevChange.
defaultStddevnumber1Uncontrolled initial standard deviation.
onStddevChange(stddev: number) => voidFires on every σ commit.
xRange[number, number]autoOverride the x-axis range.
showSigmaRegionsbooleantrueShade the ±1σ and ±2σ regions under the curve.
sigmaMinnumber0.2Minimum σ the slider can reach (must be > 0).
sigmaMaxnumber3Maximum σ the slider can reach.
meanMinnumber-3Minimum μ the slider can reach.
meanMaxnumber3Maximum μ the slider can reach.
showControlsbooleantrueRender the μ / σ sliders.
showAxisbooleantrueRender the x-axis baseline and tick labels.
transitionTransitionSPRINGS.smoothSpring for the curve / region / guideline updates.
classNamestringMerged onto the root <div> via cn().

Accessibility

  • The root <div> is role="figure" with a visually-hidden title plus an aria-live="polite" summary that announces N(μ, σ²), μ, σ, and the x-range whenever a slider commits.
  • The SVG is role="img" with the same accessible name; inner paths and the guideline are decorative.
  • Each slider is the library's LabeledSlider, a native <input type="range"> wrapper with full keyboard support (arrows, Home, End) and aria-valuenow / aria-valuetext.
  • Motion respects prefers-reduced-motion: reduce — all springs collapse to an instant swap.

Credits

  • Extracted from: craftingattention (app/src/lessons/primitives/viz/NormDistributionViz.tsx). The original was a four-panel LayerNorm pipeline widget — raw / centered / scaled / γ·x + β histograms wired to a training-step scrubber, predict-mode quizzes, and per-narration plumbing. The library extract is the underlying statistics primitive: a single N(μ, σ²) bell curve with shaded ±σ bands and standard μ / σ controls.