Labels and Annotations
How a few sentences of text turn a chart into a self-explaining story
A chart can be technically perfect — right type, right encoding, right colors — and still fail because the reader doesn't know what they're looking at. Labels and annotations are the small, unglamorous step that turns a chart into something a colleague or client can understand without you in the room.
This page is about three pieces of text:
- Titles, subtitles, and axis labels — the chart's name tag.
- Annotations — text placed on the chart pointing at something specific.
- Captions and notes — the small print explaining caveats.
Titles, subtitles, axis labels
The bare minimum on any chart:
- A title that states what the chart shows.
- Axis labels with units.
- A legend title (if the chart has a legend).
The single most common mistake on beginner charts: a title like
"chart" and axis labels of lifeExp. Take 30 seconds — write
words a stranger could read.
Titles with a takeaway
A good title doesn't just describe — it summarizes the story:
- Weak: "Sales by month."
- Strong: "Sales grew 23% in Q4, the steepest jump since 2019."
A descriptive title says what the data is. A narrative title says what the chart means. Both are valid; narrative is better when the chart is intended to make a point.
Annotations on the chart
For points you want to call out specifically — the peak, the
outlier, the day something happened — use fig.add_annotation(...).
The annotation:
text=is what to write (HTML<br>for line breaks).showarrow=Truedraws an arrow from the text to (x,y).ax,ayare pixel offsets from the point to the text.
Annotations are how you direct attention. A chart with thoughtful annotations reads itself.
Adding reference lines
Often the interesting thing in a chart is a value crossing some
threshold. Use fig.add_hline or fig.add_vline:
Reference lines split the chart into meaningful regions — in this case, four quadrants of "rich/poor × high/low life expectancy." The eye instantly reads which quadrant each country falls in.
Captions: the fine print
Plotly Express doesn't have a built-in "caption" argument, but you can add one via a layout annotation at the bottom:
The trick: xref="paper" and yref="paper" place the text in
chart-relative coordinates (0=left, 1=right) instead of data
coordinates. Combined with negative y, the text sits below the
plot area.
Captions are where you note:
- Source: "Source: WHO Global Health Estimates, 2024"
- Method: "Smoothed with 7-day moving average."
- Caveats: "2020 data is partial."
A chart without these is one step away from misinformation.
A summary checklist
Every chart you ship should have:
- A clear title (descriptive or narrative — your choice).
- Axis labels with units.
- A legend title if there's a legend.
- Any necessary annotations pointing at key moments.
- Reference lines for important thresholds.
- A caption with source and method.
- A hover that fills in details for any data point.
Skip any of these and the reader has to work harder. Some of that work, they won't bother to do.
Check your understanding
What is the difference between a descriptive title and a narrative title for a chart?
Descriptive titles are shorter than narrative titles.
They are the same thing.
A descriptive title states what the chart shows ("Sales by month"); a narrative title summarizes the takeaway the chart is intended to convey ("Sales grew 23% in Q4").
Narrative titles are required by Plotly.
Which Plotly Express / Plotly function lets you add a horizontal reference line at a specific y-value, with optional label?
fig.add_text(...)
px.hline(...)
fig.add_hline(y=..., annotation_text=...)
fig.draw_line(...)
Why is adding a caption with the data source important even for an internal chart?
It is required by GDPR.
It triples the chart's resolution.
It lets future readers (including your future self) trust, verify, and reproduce the chart — and it makes the chart safer to share outside its original context.
It makes the chart load faster.