# Chart Annotation

> Titles, labels, reference lines, callouts, legends, and provenance on a chart - writing the takeaway rather than the subject, direct labelling instead of legends, benchmark bands with their stage and vintage, and the footnote discipline that makes a figure checkable. Trigger on "chart title", "caption", "legend", "annotate", "label the chart", "reference line", "benchmark line", "footnote", "what should the title say", "callout".

- Skill: `lukehle/chart-annotation` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lukehle/chart-annotation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lukehle/chart-annotation/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Lukehle (https://skillmd.com/u/lukehle)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/lukehle/chart-annotation

---


# Chart annotation

Annotation is where a chart stops being a picture of data and becomes a statement someone can act on.
It is also the cheapest quality improvement available — mostly words, no code.

---

## The title states the finding, not the subject

The highest-leverage rule in this pack.

| Subject title (weak) | Takeaway title (strong) |
|---|---|
| ARR Bridge | Churn offset half of new ARR this quarter |
| Monthly Revenue | Revenue growth has flattened since March |
| Cohort Retention | Cohorts since January retain 6 points better at month 3 |
| Budget vs Actual | Three departments account for 80% of the overspend |
| Cash Forecast | Runway reaches 11 months under the plan hiring pace |

The subject can be a smaller subtitle underneath. But the headline is what the reader takes away, so
it should be **what you want them to take away**.

Two disciplines follow from this:

1. **If you cannot write the takeaway title, you do not yet know what the chart is for.** That is a
   signal to stop and reconsider the chart, not to fall back on a subject title.
2. **The title must be defensible.** It is a claim. If the data does not support it, change the
   title — never overstate to make a slide land.

For an exploratory tool where the reader draws their own conclusion, a subject title is correct. Know
which one you are building.

---

## Direct labels beat legends

A legend forces a lookup: read the colour, find the swatch, map back. Direct labels remove it.

- **Line charts**: label at the right end of each line, in the line's colour. No legend at all.
- **Bar charts**: value labels on or beside the bars.
- **Stacked**: label inside bands where they are wide enough; a legend only for the thin ones.
- **Scatter**: label the notable points, not all of them.

Keep a legend when there are many series, when the same legend serves several charts, or when marks
are too small to label. Then: order legend entries **to match the visual order** of the series —
alphabetical order forces the lookup you were trying to remove.

Use `chartkit.avoidOverlap` to separate crowded end-of-line labels while preserving their order.

---

## Reference lines and bands

Context turns a number into a judgement.

| Reference | Use |
|---|---|
| **Target / plan** | Solid, muted, labelled with its value and version |
| **Prior period** | Dashed, lighter |
| **Benchmark band** | Shaded region with the range labelled |
| **Threshold** | A rule where crossing means something — zero cash, a covenant |
| **Average / median** | Only if the reader needs it; often clutter |

Rules:
- **Label the line on the line**, at its end. An unlabelled rule is a mystery.
- **Muted, behind the data.** A reference line competing with the series inverts the hierarchy.
- **Name the version**: "Plan (board approved Jan-26)". Plans get revised, and an unlabelled plan is
  unreconcilable three months later.
- **Benchmarks carry source, vintage, and stage**: "SaaS median NRR 101% (2026, mid-market)". A
  mid-market benchmark against an early-stage company misleads even when the number is right.

---

## Callouts

Point at the two or three things that matter. More than that and none of them are emphasized.

Good callouts:
- The peak or trough, with its value and date
- The point where a trend changed, with the reason
- The current value, when the chart is mostly historical
- An outlier, with its explanation

**A callout that just repeats the value is not a callout.** `$210K` on a bar already labelled `$210K`
adds nothing. `$210K — lowest since Jan, two enterprise deals slipped` is a callout.

Keep them short, connect them to their mark with a thin leader line, and never let them obscure data.

---

## Event annotation

Vertical rules for discrete events; shaded regions for periods.

- Short labels, rotated only if unavoidable.
- Muted styling — events are context, not data.
- **A definition change gets an annotation and a visible break in the series.** A smooth line across a
  definition change is a false continuity claim, and it is the most damaging unannotated event
  because it is invisible.

---

## Axis labelling

- **Units once, in the axis title or the tick format** — never repeated on every tick and also in the
  title.
- **Pin the unit for the whole axis.** Mixing `$1.2M` and `$900K` makes the reader do unit
  arithmetic; choose `M` and accept `$0.9M`.
- **Say when an axis is truncated or log**, in the axis label. A truncated axis that is not labelled
  as such is a misrepresentation.
- Drop an axis title entirely when the tick format makes it obvious — `$4.8M` needs no "Revenue
  (USD millions)" above it.
- Fewer ticks than you think. Five or six is usually right; the gridlines carry the rest.

---

## Provenance — what makes a figure checkable

Every data chart carries a footer:

```
Data as of 2026-08-19 14:20 ET · Period Jul 2026 (closed)
Source: finance.gl_summary · Subscription revenue agrees to GL 4100, variance $0.00
```

- **Timezone always.** "14:20" is not a time.
- **Period status** — open periods can still move, and the reader must know.
- **Say if it has been proven**, and give the variance. That one line changes how the number is
  received.
- Small and muted (`--text-xs`, `--ink-muted`). Present, not prominent.

---

## Footnotes

For things that qualify the reading:

- Scope exclusions — "excludes intercompany"
- Restatements — "Q1 restated for the revenue reclass"
- Suppression — "cells with fewer than 5 customers suppressed"
- Estimates — "August is a forecast"
- Definition — a link to the metric definition, or the definition inline

**Anything that would change a reader's interpretation goes near the number, not in a footnote.**
Footnotes are for detail; qualifications that matter belong in the chart.

---

## Checklist

- [ ] Title states a finding you can defend
- [ ] Every series labelled directly, or a legend ordered to match the visual
- [ ] Units stated once, pinned per axis
- [ ] Truncated or log axes labelled as such
- [ ] Reference lines labelled with value and version
- [ ] Benchmarks carry source, vintage, and stage
- [ ] Two or three callouts, none merely repeating a value
- [ ] Definition changes annotated with a visible break
- [ ] Provenance footer with as-of, timezone, period status, source
- [ ] Nothing on the chart is decorative

---

## Related skills

- `chart-selection` — writing the takeaway before building
- `microcopy-and-states` — the wider wording discipline
- `data-typography` — how the labels are set
- `ui-antipatterns` — unlabelled truncation and false precision
- `bridge-charts`, `timeseries-finance`, `cohort-charts` — form-specific annotation

