Skip to content

Anti-Patterns

A catalog of what goes wrong: misleading practices that distort the truth, design anti-patterns that obscure the story, and the statistical integrity rules that keep charts honest.

Misleading practices

Anti-patternWhy it misleadsFix
Truncated y-axis on bar chartsExaggerates small differencesStart at zero
Dual y-axesArbitrary scale alignment implies false correlationSide-by-side charts or indexed values
3D effectsTilted surfaces distort perceived valuesUse flat 2D charts
Cherry-picked time rangesSupports a narrative without full contextShow complete timeframe; note any filtering
Bubble size by radiusExponential area distortionSize by area
Unnormalized choroplethShows population density, not the intended variableNormalize per capita / per unit
Rainbow color scalesPerceptually non-uniform; meaningless orderingUse sequential or diverging palettes

See Axes & Grid Lines for the baseline rules behind the first row, and Color & Palettes for palette guidance that prevents the last two.

Design anti-patterns

Anti-patternProblemFix
Spaghetti chartToo many overlapping linesHighlight key lines; grey the rest; small multiples
Pie chart with 10+ slicesUnreadable small slicesUse bar chart or group into "Other"
Decorative colorColor without meaning adds noiseUse grey for non-meaningful elements
Legend far from dataForces eye-travel; increases cognitive loadDirect labeling
Rotated axis labelsHard to readAbbreviate labels or use horizontal bars
Over-annotationCompeting for attention dilutes the messageMaximum 3-4 annotations; prioritize
Missing contextData without comparison has no storyAdd reference lines, targets, time comparisons
Stacking many small segmentsImpossible to read individual valuesGroup small segments; use direct comparison

See Labels & Legends for direct-labeling technique and Annotations for the 3–4 annotation ceiling.

Statistical integrity

  • Start axes at zero for area / bar charts unless there is a compelling, stated reason not to
  • Avoid implying causation from correlation (scatter plots show association only)
  • Show confidence intervals and error bars when data has uncertainty
  • Don't obscure sample size (box plots hide it; add individual points for small N)
  • Tables are valid — sometimes better than charts for conveying precise values

Worked example: a shared baseline instead of three deceptive single-bar charts

A frequent anti-pattern is splitting a comparison across three charts with different y-axis ranges — each one tuned to "look interesting" in isolation. The honest alternative is one chart with a shared scale, so identical bar lengths mean identical values:

bpc
chart bar-split {
  title = "Singapore leads the world in all three PISA 2022 subjects"
  description = "Mean scores in Mathematics, Reading, and Science for 15-year-olds"
  source = "OECD PISA 2022"
  valueLabels = true
  sharedScale = true

  data {
    _series = "Mathematics","Reading","Science"
    "Singapore" = 575,543,561
    "Japan"     = 536,516,547
    "Korea"     = 527,515,528
    "Estonia"   = 510,511,526
    "Canada"    = 497,507,515
    "Australia" = 487,498,507
  }
}

Done right

sharedScale = true forces every panel onto the same baseline-zero axis, so the eye can compare Mathematics directly against Reading directly against Science. valueLabels = true then exposes the exact number, removing any temptation to truncate the axis for visual drama. This is the corrective pattern for the "truncated y-axis", "dual y-axes", and "missing context" rows above. From packages/lib/src/samples/pisa-scores.bpc.

The meta-rule

TIP

Every anti-pattern traces back to a design principle being violated. If a chart feels wrong, walk back through the design principles — purposefulness, clarity, data-ink, restraint, consistency, comparison. One of them will be out of place.

See also

Released under the MIT License. Built static-first — your data never leaves the page.