Honest dataviz
A chart is read by people and executed by you. This skill turns "make it
look good" into decisions with reasons, so the result is right by
construction. Every rule here was bought with a measured failure in a
production reporting engine — none is taste.
First decision: is it even a chart?
| The data is… |
Use |
Not |
| One current value (+ trend) |
Stat tile: label, hero figure, semantic delta, small sparkline |
A one-bar bar chart |
| A handful of headline numbers |
A KPI row of stat tiles |
A grouped bar chart |
| A ratio against a limit |
A meter with the limit marked |
A two-slice pie |
| More than ~7 categories that all matter |
A table (or table + chart) |
More colours |
| A verification story (checks, statuses) |
A tracker strip: one cell per check |
Prose |
If a chart is right, the data's JOB picks the form: magnitude → bars;
trend → line/area; part-to-whole → stacked bar (horizontal when names are
long) or a two-segment donut at most; above/below a baseline → diverging
bars around zero; one series against context → emphasis (one hue, grey
rest). The most underused honest form is emphasis; the most overused
dishonest one is categorical rainbow.
Typography on charts — the two highest-leverage fixes
- At most three font sizes per view. Generated dashboards carry five
to eight; consolidating to three is the single biggest "suddenly looks
designed" move.
- Pull the weights back. Nothing above semibold. Bold everywhere is
the clearest generated-dashboard tell there is.
- Values, labels and legends wear TEXT colours (ink/soft/muted), never
the series colour. A coloured mark beside them carries identity.
The colour law
- Colour is spent on data, never on chrome. Axes, grids, panels and
labels are neutral. If a colour appears, it means something.
- Semantic pair: green = up/good/verified, red = down/fails — and
NOTHING else ever borrows those two. A red that sometimes means
"category B" destroys the one thing colour was teaching the eye.
- The semantic pair is a STATUS pair, not a chart palette. Measured:
a standard green/red pair fails colour-blind separation (deutan ΔE ≈ 5,
where ≥ 8 is safe). Legal only when polarity is ALSO carried by
position (diverging around zero), glyphs (▲ ▼ ✓), or words — colour
reinforces, never carries alone.
- Magnitude = one hue, light→dark (an ink ramp is safest). Identity
for 2–3 series = distinct hues, direct-labelled. More series than that:
fold to "Other", facet into small multiples, or emphasize one — never
generate a 9th hue.
- Validate, don't eyeball. Run any CVD simulator/validator over the
final palette against the actual surface colour, in BOTH themes. If a
pair lands in the marginal band, secondary encoding (labels, position,
texture) is mandatory, not nice-to-have.
Mark specs (the difference between crisp and mushy)
- Bars ≤ 24px thick; 4px rounded data-end, square at the baseline; grow
from one baseline. 2px gap in the SURFACE colour between touching marks.
- Lines 2px, round joins; markers ≥ 8px with a 2px surface ring.
- Sparklines: de-emphasis grey with an ink endpoint dot; ~12–28 points.
- Direct-label only the max, the min, and the point the caption is about.
A number on every point is noise wearing a badge.
- Grid and axes recessive (faintest text colour); one axis only — a dual
y-axis chart is the #1 chart mistake; use two charts or index to 100.
Honesty mechanics (what makes a dashboard trustworthy, not just pretty)
- A receipts panel must add up to its own headline. If rows are
rounded independently, they won't (measured: $819,771 of rows under an
$819,770 headline). Show evidence at full precision.
- A sample size belongs to its figure, not to the page. "n=1,204" as
a page-level fact beside a metric computed on 218 is a wrong number
with a right value.
- A component is not a peer. Two equal tiles invite addition; when
one is inside the other, the page invites double-counting. Render the
component subordinate and say "part of X".
- A state is not a finding. "First period, nothing to compare against"
is the absence of history — state it; never count it as doubt, and
never colour it as failure.
- Unverified figures are shown AND labelled — muted value, a plain
"not verified" flag, and the reason somewhere findable. Hiding doubt is
the one dishonesty a reader never forgives.
Anti-pattern catalogue (if the chart matches an entry, it's wrong)
Dual axes · rainbow categoricals · a hue at a diverging midpoint · pies
beyond 2–3 slices · cumulative charts implying growth while the periodic
series falls · truncated bar axes · a number on every point · gradient
fills on data · colour re-assigned when a filter changes the series count
· hover states on inert elements · decorative icons anchoring KPI corners
· light/dark mode as the flagship feature of an MVP dashboard.
Hand-drawn SVG traps (each cost a real debugging round)
- Author SVG at its rendered width. Text inside SVG scales with the
viewBox: a label authored 12px at 1044 units renders 5px in a 473px
column. Prefer HTML for labels around width-fluid charts.
- Grid cells must equal the column template — extras wrap into invisible
second rows and triple the row height silently.
- Only a render is evidence. Screenshot the result and look at it, in
both themes, at mobile width, and printed. CSS that "reads right" has
shipped invisible twice in the corpus this skill comes from.
kymira honest-dataviz · v2026.08.21 · lifetime updates included
1---2name: honest-dataviz3description: Charts and dashboards that read at a glance, survive a colour-blind reviewer, and never imply more certainty than the data has. Use this BEFORE writing any chart, graph, KPI tile, dashboard, or data visualization — in any library or in hand-drawn SVG/HTML — and whenever choosing chart colours, building a stat row, or deciding whether something should be a chart at all.4---56# Honest dataviz78A chart is read by people and executed by you. This skill turns "make it9look good" into decisions with reasons, so the result is right by10construction. Every rule here was bought with a measured failure in a11production reporting engine — none is taste.1213## First decision: is it even a chart?1415| The data is… | Use | Not |16|---|---|---|17| One current value (+ trend) | Stat tile: label, hero figure, semantic delta, small sparkline | A one-bar bar chart |18| A handful of headline numbers | A KPI row of stat tiles | A grouped bar chart |19| A ratio against a limit | A meter with the limit marked | A two-slice pie |20| More than ~7 categories that all matter | A table (or table + chart) | More colours |21| A verification story (checks, statuses) | A tracker strip: one cell per check | Prose |2223If a chart is right, the data's JOB picks the form: magnitude → bars;24trend → line/area; part-to-whole → stacked bar (horizontal when names are25long) or a two-segment donut at most; above/below a baseline → diverging26bars around zero; one series against context → emphasis (one hue, grey27rest). The most underused honest form is **emphasis**; the most overused28dishonest one is categorical rainbow.2930## Typography on charts — the two highest-leverage fixes31321. **At most three font sizes per view.** Generated dashboards carry five33 to eight; consolidating to three is the single biggest "suddenly looks34 designed" move.352. **Pull the weights back.** Nothing above semibold. Bold everywhere is36 the clearest generated-dashboard tell there is.373. Values, labels and legends wear TEXT colours (ink/soft/muted), never38 the series colour. A coloured mark beside them carries identity.3940## The colour law4142- **Colour is spent on data, never on chrome.** Axes, grids, panels and43 labels are neutral. If a colour appears, it means something.44- **Semantic pair**: green = up/good/verified, red = down/fails — and45 NOTHING else ever borrows those two. A red that sometimes means46 "category B" destroys the one thing colour was teaching the eye.47- **The semantic pair is a STATUS pair, not a chart palette.** Measured:48 a standard green/red pair fails colour-blind separation (deutan ΔE ≈ 5,49 where ≥ 8 is safe). Legal only when polarity is ALSO carried by50 position (diverging around zero), glyphs (▲ ▼ ✓), or words — colour51 reinforces, never carries alone.52- **Magnitude = one hue, light→dark** (an ink ramp is safest). Identity53 for 2–3 series = distinct hues, direct-labelled. More series than that:54 fold to "Other", facet into small multiples, or emphasize one — never55 generate a 9th hue.56- **Validate, don't eyeball.** Run any CVD simulator/validator over the57 final palette against the actual surface colour, in BOTH themes. If a58 pair lands in the marginal band, secondary encoding (labels, position,59 texture) is mandatory, not nice-to-have.6061## Mark specs (the difference between crisp and mushy)6263- Bars ≤ 24px thick; 4px rounded data-end, square at the baseline; grow64 from one baseline. 2px gap in the SURFACE colour between touching marks.65- Lines 2px, round joins; markers ≥ 8px with a 2px surface ring.66- Sparklines: de-emphasis grey with an ink endpoint dot; ~12–28 points.67- Direct-label only the max, the min, and the point the caption is about.68 A number on every point is noise wearing a badge.69- Grid and axes recessive (faintest text colour); one axis only — a dual70 y-axis chart is the #1 chart mistake; use two charts or index to 100.7172## Honesty mechanics (what makes a dashboard trustworthy, not just pretty)7374- **A receipts panel must add up to its own headline.** If rows are75 rounded independently, they won't (measured: $819,771 of rows under an76 $819,770 headline). Show evidence at full precision.77- **A sample size belongs to its figure, not to the page.** "n=1,204" as78 a page-level fact beside a metric computed on 218 is a wrong number79 with a right value.80- **A component is not a peer.** Two equal tiles invite addition; when81 one is inside the other, the page invites double-counting. Render the82 component subordinate and say "part of X".83- **A state is not a finding.** "First period, nothing to compare against"84 is the absence of history — state it; never count it as doubt, and85 never colour it as failure.86- **Unverified figures are shown AND labelled** — muted value, a plain87 "not verified" flag, and the reason somewhere findable. Hiding doubt is88 the one dishonesty a reader never forgives.8990## Anti-pattern catalogue (if the chart matches an entry, it's wrong)9192Dual axes · rainbow categoricals · a hue at a diverging midpoint · pies93beyond 2–3 slices · cumulative charts implying growth while the periodic94series falls · truncated bar axes · a number on every point · gradient95fills on data · colour re-assigned when a filter changes the series count96· hover states on inert elements · decorative icons anchoring KPI corners97· light/dark mode as the flagship feature of an MVP dashboard.9899## Hand-drawn SVG traps (each cost a real debugging round)100101- **Author SVG at its rendered width.** Text inside SVG scales with the102 viewBox: a label authored 12px at 1044 units renders 5px in a 473px103 column. Prefer HTML for labels around width-fluid charts.104- Grid cells must equal the column template — extras wrap into invisible105 second rows and triple the row height silently.106- **Only a render is evidence.** Screenshot the result and look at it, in107 both themes, at mobile width, and printed. CSS that "reads right" has108 shipped invisible twice in the corpus this skill comes from.109110---111*kymira honest-dataviz · v2026.08.21 · lifetime updates included*