For comparing multiple trends over time; useful for directions of changes, as well as absolute values to some degree. Requires values to be on the same scale.
If your data is “wide” (each row might contain multiple
observations taken at the same time),
we need it to be made “tall” (each row is exactly one
data-point).
If you already have tall data, just skip the
pivot_longer().
membership_raw <- data.frame(overall=c(65.26,55.21,56.29),
deu=c(11.66, 10.31, 9.26),
gbr=c(10.39, 8.28, 9.57),
esp=c(5.51, 4.32, 4.83))
membership_percent <-
membership_raw %>%
sapply(., function(col){col/col[1]}) %>%
as.data.frame(.) %>%
mutate(., year=2019:2021) %>%
pivot_longer(!year, names_to="market", values_to="membership") %>%
mutate(market=factor(market,
levels=c("deu","gbr","esp","overall")))
labels <- as_labeller(c("deu"="Germany",
"gbr"="the UK",
"esp"="Spain",
"overall"="the Entire EU"))
head(membership_percent)
## # A tibble: 6 × 3
## year market membership
## <int> <fct> <dbl>
## 1 2019 overall 1
## 2 2019 deu 1
## 3 2019 gbr 1
## 4 2019 esp 1
## 5 2020 overall 0.846
## 6 2020 deu 0.884
The trick is to create a copy of the faceting variable(s) and group on that, so that the background data are grouped but not faceted into different panels.
ggplot(membership_percent, aes(x=year, y=membership)) +
facet_grid(cols=vars(market), labeller = labels) +
# the background lines present in every panel
geom_line(data=membership_percent %>%
mutate(market2=market) %>%
dplyr::select(-market),
aes(group=market2),
color="gray") +
# the highlighted line corresponding to each panel
geom_line() +
# arranging the plot
scale_x_continuous(breaks = seq(2019, 2021, by = 1)) +
scale_y_continuous(expand = c(0.2,0.2)) +
coord_cartesian(xlim=c(2019,2021)) +
labs(title="Membership decreased from 2019",
subtitle="in European Markets, in the years 2020 and 2021",
y="Membership count relative to 2019") +
theme_minimal()
my_color <- "#233F7D"
ggplot(membership_percent, aes(x=year, y=membership)) +
facet_grid(cols=vars(market), labeller = labels) +
# the background lines present in every panel
geom_line(data = membership_percent %>%
mutate(market2=market) %>%
dplyr::select(-market),
aes(group=market2),
color = "gray") +
# the highlighted line corresponding to each panel
geom_line(color = my_color,
linewidth = 1) +
geom_point(data = dplyr::filter(membership_percent, year!=2020),
size=2, color=my_color) +
geom_text(data = dplyr::filter(membership_percent, year==2021),
aes(label = scales::percent(membership)),
nudge_y = 0.02 * c(1, -1, 1, 1),
# for some reason, this needs to be in the order the categories appear in the data set, not their order on the plot
color = my_color,
size = 5) +
# arranging the plot
scale_x_continuous(breaks = seq(2019, 2021, by = 1),
expand = c(0.3,0.3)) +
coord_cartesian(xlim=c(2019,2021), ylim=c(0.7,1)) +
labs(title=stringr::str_interp("<span style='color:${my_color}'>**Membership decreased**</span> from 2019"),
subtitle="in European Markets, in the years 2020 and 2021",
y="Membership count relative to 2019") +
# theme
theme_minimal() +
theme(plot.title=element_markdown(size=18, color='#535353'),
plot.subtitle=element_text(size=14),
strip.text = element_text(angle = 0, size = 14,
color='#818181'),
text = element_text(color='#818181'),
panel.grid = element_blank(),
axis.ticks.y = element_blank(),
axis.text.y = element_blank(),
axis.title.x = element_blank())