Sometimes it's better to be discrete

Counting uncertainty · repeated signs

When dots, icons, and repeated signs beat bars, blobs, and smooth densities.

Should I leave now or wait for the bus?

What should the chart help people do?
Possible worlds
Probability?

estimate it in panel 01 first

Natural frequency82

of 100 commuters make the connection

Expected wait7.7

minutes, kept as measurable length

01 · Continuous

Area is the answer

?

A density curve represents the probability correctly, but the reader must estimate a shaded area. Commit to a guess before revealing the count so you can compare the two tasks.

Skip to data table
A shaded density area poses the estimation question for a 10 minute threshold.
02 · Possible outcomesSuggested

50 possible arrivals

50 tokens

Kay and Hullman's quantile dotplot: each dot is one equally likely arrival, stacked so interval probability becomes literal counting.

Skip to data table
50 quantile tokens rendered as dots, judged against a 10 minute threshold.

Live results from diagnoseTokenEncoding for exactly the encoding rendered in panel 02 — sabotage it and the critique updates with it.

No warnings. The tokens declare their semantics, the count strategy matches the meaning, and 50 visible tokens is within budget.

03 · Natural frequency

Risk is easier as people

18/100

The same threshold, translated: out of 100 commuters making this exact choice, the highlighted people miss their connection. Fixed denominators keep percentages honest and countable.

Skip to data table
18 of 100 commuters miss the connection when the bus must arrive within 10 minutes.
04 · Hypothetical outcomes

One possible morning at a time

morning 1

Hypothetical outcome plots show one possible result at a time. Watch the simulated mornings accumulate, then compare them with the quantile dotplot in panel 02.

Skip to data table
Morning 1 of a shuffled sequence of possible bus arrivals, judged against a 10 minute threshold.
05 · Hybrid encoding

Combine a precise scale with countable signs.

The bar gives the expected wait a measurable length. Each bus sign on top represents two minutes, including a partial sign at the end. The values under the axis show the total represented.

Skip to data table
Expected wait is 7.7 minutes, represented as one bus sign for every two minutes.
06 · Suggested encoding

Quantile dotplot

This task asks readers to estimate probability from a distribution. Quantile tokens turn probability mass into countable possible outcomes.

Token type
dot
Semantics
possible-outcome
Count
quantile
Layout
dotplot
cdf-with-thresholddensity-with-threshold

The recommendation is deterministic: same task, same suggested encoding. API names for wiring it up live in the implementation section below.

A century of counting
1926

ISOTYPE

Neurath · Reidemeister · Arntz

Repeat a sign, never grow it — quantities become countable things.

1995

Natural frequencies

Gigerenzer & Hoffrage

Show risk as 18 visible cases among 100 commuters.

2015

Hypothetical outcome plots

Hullman · Resnick · Adar

Uncertainty as possible worlds, drawn one at a time.

2016

Quantile dotplots

Kay · Kola · Hullman · Munson

“When(ish) is my bus?” — a distribution you can count.

Pictograms, infographics, icon arrays, and uncertainty displays share a useful move: replace an abstract magnitude with things a reader can count—units, cases, and possible worlds.

Implementation

TokenLayer generates the countable marks.

Semantics first, then placement, then marks: generateTokens decides what each token means, the dotplot layout Wilkinson-stacks the quantiles, andtokenLayer emits ordinary Semiotic scene nodes with the same canvas, SVG, hover, focus, and accessible-table machinery as every other custom chart.

JSX
import { XYCustomChart } from "semiotic/xy" import { diagnoseTokenEncoding, generateTokens, suggestTokenEncoding, tokenLayer, } from "semiotic/recipes" // 1 · Say what a repeated mark MEANS before anything is drawn. const encoding = { tokenType: "glyph", icon: "bus", // the built-in ISOTYPE bus sign tokenSemantics: "possible-outcome", countStrategy: "quantile", // Kay/Hullman: equally likely arrivals tokenCount: 50, layout: "dotplot", // Wilkinson-stacked quantile dotplot } // 2 · The records carry the ledger and a live design critique. const tokenSet = generateTokens(arrivalSamples, encoding) tokenSet.diagnostics // e.g. TOO_MANY_VISIBLE_TOKENS if you ask for 800 // 3 · Any custom layout stamps them as real scene nodes — canvas + SVG, // hover, keyboard nav, transitions, accessible rows, for free. function busDotplotLayout(ctx) { const { height } = ctx.dimensions.plot const layer = tokenLayer({ input: tokenSet, options: { tokenSize: 17, cellHeight: -19, // negative step: stack up from the axis y: height - 32, valueToX: (arrival) => ctx.scales.x(arrival), color: (t) => (t.sample <= threshold ? "#236d99" : "#c93d3d"), datum: (t) => ({ arrival: t.sample, quantile: t.quantile }), pointId: (t) => `outcome-${t.index}`, }, }) return { nodes: layer.nodes, overlays: <ThresholdLine /> } } <XYCustomChart data={arrivalData} layout={busDotplotLayout} xExtent={[0, 22]} /> // 4 · Or ask for the encoding first — task in, semantics out. suggestTokenEncoding({ taskIntent: "estimate probability", dataType: "distribution" }) // → { recommendedEncoding: "quantile-dotplot", tokenEncoding, rationale, … }