Skip to course content
Free R data course

R Foundations for Data Analysis

Unit 07.03: The title states the finding

A chart will be screenshotted into a slide deck and lose everything around it. Whatever it needs to be understood has to be inside it.

The title states the finding; the caption carries the limitation

Default labels come from the code — often an expression like reorder(ward, per_1000), which is meaningless to a reader. Every published chart needs its labels written.

A title that names the topic ('Visits by ward') wastes the most-read line on the page. A title that states the finding ('West records the highest visit rate') means a reader who reads nothing else still leaves with the point.

The caption is where the source and the limitation go. It is the only place a chart can say 'East reported one month only', and without it the bars imply a comparability that does not exist.

Export belongs in code. ggsave() fixes size and resolution, so the file is the same every time it is rebuilt.

This block labels a bare chart and exports it at print resolution.

suppressPackageStartupMessages(library(ggplot2))

visits <- data.frame(ward = c("North", "South", "East", "West"),
                     per_1000 = c(34.9, 40.3, 33.2, 45.1))

bare <- ggplot(visits, aes(reorder(ward, per_1000), per_1000)) + geom_col()

labelled <- bare +
  labs(
    title    = "West records the highest visit rate",   # the finding, not the topic
    subtitle = "Visits per 1,000 residents, January to March 2026",
    x = NULL,
    y = "Visits per 1,000 residents",
    caption  = "Source: ward monthly returns. East reported one month only."
  ) +
  theme_minimal()

out <- file.path(tempdir(), "rates.png")
ggsave(out, labelled, width = 6, height = 3.5, dpi = 300)

cat("Default axis label would have been the expression:", "reorder(ward, per_1000)", "\n")
cat("Title states the finding, so a reader who reads nothing else still learns it.\n")
cat("Caption carries the limitation that the bars cannot show.\n\n")
cat("Exported at 300 dpi:", basename(out), file.size(out), "bytes\n")
cat("Screenshotting the preview pane would have given a different size every time.\n")

Without labels the y axis would have read reorder(ward, per_1000). The labelled version carries the finding in the title, the measure and period in the subtitle, the units on the axis, and East's one-month limitation in the caption. Exported at 300 dpi it comes out at a fixed size — a screenshot of the preview pane would differ with the window every time.

The mistake this prevents

The mistake is exporting by screenshot. The resolution depends on the monitor, the crop depends on the window, and the chart cannot be rebuilt identically when the data changes.

Takeaway

Write the title as the finding, put units on the axes, and use the caption for source and limitations. Export with ggsave() at a stated size and resolution so the file is reproducible.