Skip to content
microcharts
ReferenceFrontierBiasStrip

BiasStrip

"A Bland–Altman read: the difference between two measurement methods, plotted against their mean, with limits of agreement."

encodes
vertical position of the paired difference
precision
high
nodes
1 per pair (≤ 40) + band + 2 lines

A new device tracks its reference closely and still reads about 2 units high. BiasStrip plots that offset: each dot is one pair placed at its mean and its difference, the dashed line is perfect agreement, the accent line is the measured bias, and the faint band is the limits of agreement. The y-axis is symmetric about zero, so a systematic offset reads as the whole cloud sitting above or below the line. Dots render at 75% opacity so overplot reads as density, and pairs beyond the limits are enlarged and re-inked so outliers read on shape, not color alone.

BiasStrip
interactive · 5.29 kB · static · 2.76 kB

Install

Import & usereact/bias-strip
import { BiasStrip } from "@microcharts/react/bias-strip";// pairs — real values under “Sample data” below<BiasStrip data={pairs} title="Device vs reference" />
Sample data
// a ~+2 bias with noise and two pairs beyond the limits of agreementconst pairs = [  1.8, 2.4, 1.5, 2.9, 2.1, 1.2, 2.6, 3.0, 1.9, 2.3, 6.5, 2.0, 1.7, 2.8, 2.2, -1.5, 2.5, 1.6, 2.7,  2.0,].map((d, i) => ({ a: i + d, b: i }));
Needs package + stylesheetSet up with AI

Try it

When to use it

Use it to check whether a new instrument, method, or model agrees with a reference, and for instrument drift in a KPI card. For unpaired samples use MicroScatter; for a single time series use Sparkline.

Two methods can correlate perfectly and still disagree by a constant offset. BiasStrip plots the difference, so that offset shows up as distance from the zero line where a correlation plot would hide it along the diagonal.

Sizing

Variants

The band is the classic ±1.96σ limits of agreement. limits widens or tightens it (2.58 for about 99%) without changing what any mark means.

99% limits of agreement
no caption
bigger dots

Edge cases

empty
fewer than 5 pairs — dots only, no band
perfect agreement — band collapses to a hair

Empty data draws just the frame with "No data." as the summary. Under 5 pairs the limits aren't meaningful, so the band and bias line drop out and only the dots and the zero reference remain: the chart makes no interval claim at that sample size, and the mean difference is still stated in the summary. When the two methods agree perfectly the band collapses to a hair around the zero line rather than vanishing, so the measured result stays visible. Pairs with a non-finite value are dropped before the stats and the count. Past 40 pairs the dots are uniformly downsampled for display, while the bias and limits still use every pair.

Four homes

Accessibility

The accessible name is the bias plus the evidence-backed agreement share — "Bias +2.21 across 20 pairs; 90% within the limits of agreement." — or the shorter "Bias +2 across 4 pairs." when there are too few pairs to draw limits. Localizing carries the number format through: with locale="de-DE" the same chart reads "Bias +2,21 across 20 pairs; 90% within the limits of agreement." The interactive entry steps pairs ordered by mean and announces each pair's mean, difference, and whether it clears the limits.

The interactive entry follows the shared interaction contract: arrow keys rove between units on both axes, Home and End jump to the ends, and a click, tap, Enter or Space selects a unit — pinning its readout so it survives blur, until you select it again or press Escape. On touch, a tap pins and a drag scrubs.

Props

PropTypeNotes
data*{ a; b }[]Paired measurements.
limitsnumberk in bias ± k·σ (default 1.96 ≈ 95% limits of agreement).
label"bias" | "none"Seat-gated bias caption (default) or hidden.
rnumberBase dot radius, clamped [1, 3].
animatebooleaninteractiveOpt-in entrance motion when the chart mounts client-side — add import "@microcharts/react/motion" once. Inert on the server, on hydrated server HTML, and under prefers-reduced-motion.

Plus the shared grammar — data, domain, color, title, summary, format — and the layout props (width, height, className, style) that every chart accepts. Interactive entries also share animate and live, and — wherever a chart has more than one navigable unit — onActive, onSelect, selectedIndex and defaultSelectedIndex; and — wherever the chart shows a hover value — readout. See the shared grammar.

Related charts