Overview #
A bump plot (or bump chart) is a way to show how rankings change over time.
It shows relative ordering rather than absolute values.
Visually, bump plots look like a variation of line plots.
When to use #
Use a bump plot when you’re trying to convey details about relative ordering.
They’re not so great for communicating absolute values over time. For something like that, stick to a more conventional line plot.
Data #
The underlying data should include:
- A categorical field that includes the set of things that’s tracked over time.
- A time dimension (such as years).
- A ranking of the categorical thing within time dimensions. This can be derived from numerical values.
As a simple example, let’s say we’re tracking a race (like a 5k or a 100m dash), and there are three competitors. They race each other over and over.
Here’s what the dataset might look like.
example <- tribble(
~runner, ~year, ~rank,
"Arnold", 2019, 1,
"Arnold", 2020, 2,
"Arnold", 2021, 1,
"Arnold", 2022, 3,
"Bob", 2019, 2,
"Bob", 2020, 1,
"Bob", 2021, 3,
"Bob", 2022, 1,
"Charles", 2019, 3,
"Charles", 2020, 3,
"Charles", 2021, 2,
"Charles", 2022, 2
)
kable(example)
runner | year | rank |
---|---|---|
Arnold | 2019 | 1 |
Arnold | 2020 | 2 |
Arnold | 2021 | 1 |
Arnold | 2022 | 3 |
Bob | 2019 | 2 |
Bob | 2020 | 1 |
Bob | 2021 | 3 |
Bob | 2022 | 1 |
Charles | 2019 | 3 |
Charles | 2020 | 3 |
Charles | 2021 | 2 |
Charles | 2022 | 2 |
R #
The simplest way to generate bump plots in R is with the ggbump package by David Sjoberg.
# install.packages("ggbump") # run this if the package hasn't already been installed
library(ggbump)
Let’s use the example data from above.
example
## # A tibble: 12 × 3
## runner year rank
## <chr> <dbl> <dbl>
## 1 Arnold 2019 1
## 2 Arnold 2020 2
## 3 Arnold 2021 1
## 4 Arnold 2022 3
## 5 Bob 2019 2
## 6 Bob 2020 1
## 7 Bob 2021 3
## 8 Bob 2022 1
## 9 Charles 2019 3
## 10 Charles 2020 3
## 11 Charles 2021 2
## 12 Charles 2022 2
Now create a bump chart.
example %>%
ggplot(aes(x = year, y = rank, color = runner)) +
geom_bump()
Let’s dress it up some.
It’s nice to have the label for each category both on the left and on the right.
We can also enhance the plot by:
- Changing the theme
- Adding points for each observation
- Ordering the ranks so #1 is at the top
example %>%
ggplot(aes(x = year, y = rank, color = runner)) +
geom_bump() +
geom_point(size = 8) + # add points
geom_text(data = example %>% filter(year == min(year)), aes(x = year - .1, label = runner), hjust = 1) +
geom_text(data = example %>% filter(year == max(year)), aes(x = year + .1, label = runner), hjust = 0) +
scale_x_continuous(limits = c(2018.5, 2022.5)) +
scale_y_reverse(breaks = c(1,2,3)) +
theme_minimal() +
theme(
legend.position = "none",
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()
) +
labs(
title = "Race Rankings",
x = "Year",
y = "Rank"
)
And there we have it: a fairly simplistic but complete bump plot that conveys rankings over time.
Resources #
*Bump Chart – a detailed walkthrough on how to create a bump plot in ggplot2 without the conveniences of ggbump
.