Bump Plot

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.