Adding context to a single figure
A lone number — say, $10M in sales for last month — carries little meaning on its own. To interpret the figure, you need a frame of reference: how it compares to previous months, or to similar organizations. A line chart over time provides exactly that kind of context, placing today's value against a historical trend.
Consider a more sobering example: COVID deaths per 100,000 residents in Massachusetts. A simple time-series plot makes recent figures comparable to the two earlier peaks.
death_pp %>%
filter(state == "MA") %>%
ggplot(aes(date, death_pm_rm)) +
labs(y = "deaths per 100,000") +
geom_line(color = "blue")
show code to load death_pp
# cdc covid data records New York City seperately from New York state
cdc_pops <- pops %>%
mutate(pop = if_else(state == "NY", pop - 8400000, pop)) %>%
add_row(name = "New York City", state = "NYC", pop = 8400000)
# http -d "https://data.cdc.gov/api/views/9mfq-cb36/rows.csv" > cdc_cases.csv
cdc_cases <- read_csv("cdc_cases.csv") %>%
select(state, submission_date, new_death, tot_death) %>%
mutate(date = mdy(submission_date)) %>%
arrange(date) %>%
group_by(state)
death_pp <- cdc_cases %>%
left_join(cdc_pops, by = "state") %>%
drop_na(pop) %>%
mutate(death_pm = new_death * 1000000 / pop) %>%
mutate(death_pm_rm = rollmean(death_pm, 7, fill=NA, align="right"))
Spaghetti with a muted background
Time alone is not the only dimension of context. To see how Massachusetts fared relative to the rest of the country, you can overlay its line onto those of all other US states, rendered as a dim backdrop. Although there is no universally accepted name for this design, "muted-spaghetti chart" captures the idea well.
In ggplot2, the implementation is straightforward: add a second geom_line fed by a different data frame, drawing the background series first so the foreground line is layered on top.
death_pp %>%
filter(state == "MA") %>%
ggplot(aes(date, death_pm_rm)) +
labs(y = "deaths per 100,000") +
geom_line(data = death_pp, aes(group = state), color = "grey", size = 1, alpha = 0.5) +
geom_line(aes(y = death_pm_rm), color = "blue")
Repeating the pattern across facets
Examining one state in isolation is limiting. facet_wrap lets you create small multiples — one panel per state — but combining it with a muted-spaghetti background requires care. The subtlety lies in how the grouping variable for the background lines is specified.
death_pp %>%
filter(state %in% c("MA", "VT", "CT", "RI", "NH")) %>%
ggplot(aes(date, death_pm_rm)) +
labs(y = "deaths per 100,000") +
geom_line(data = death_pp %>% rename(s = state),
aes(group = s), color = "grey", size = 1, alpha = 0.5) +
geom_line(color = "blue") +
facet_wrap(~state, ncol = 3)
The solution hinges on renaming the grouping column so that the faceting is applied only to the primary line; the spaghetti series are then drawn uniformly on every panel, without being split into facets themselves.



