# How to Easily Create a Bump Chart in R Using ggplot2

A bump chart is a type of chart that shows rankings of different groups over time instead of absolute values to emphasize the order of the groups instead of the magnitude of change.

This tutorial explains how to easily create a bump chart in R using ggplot2.

## Example: Creating a Bump Chart

To create a bump chart in R, we first need to load two packages: dplyr and ggplot2:

```library(ggplot2) #for creating bump chart
library(dplyr) #for manipulating data```

Next, we’ll create some data to work with:

```#set the seed to make this example reproducible
set.seed(10)

data <- data.frame(team = rep(LETTERS[1:5], each = 10),
random_num = runif(50),
day = rep(1:10, 5))

data <- data %>%
group_by(day) %>%
arrange(day, desc(random_num), team) %>%
mutate(rank = row_number()) %>%
ungroup()

#  team  random_num   day  rank
#1 C          0.865     1     1
#2 B          0.652     1     2
#3 D          0.536     1     3
#4 A          0.507     1     4
#5 E          0.275     1     5
#6 C          0.615     2     1```

This data frame simply shows the “rank” of five different teams across a time span of 10 days.

We can use ggplot2 to create a bump chart to visualize the rank of each team during each day over this time span:

```ggplot(data, aes(x = day, y = rank, group = team)) +
geom_line(aes(color = team, alpha = 1), size = 2) +
geom_point(aes(color = team, alpha = 1), size = 4) +
scale_y_reverse(breaks = 1:nrow(data))``` This bump chart shows the data in the format that we want, but it’s fairly ugly. With some aesthetic changes, we can make this chart look much better.

## Styling the Bump Chart

To make the chart look better, we can use the following theme created by Dominik Koch:

```my_theme <- function() {

# Colors
color.background = "white"
color.text = "#22211d"

# Begin construction of chart
theme_bw(base_size=15) +

# Format background colors
theme(panel.background = element_rect(fill=color.background,
color=color.background)) +
theme(plot.background  = element_rect(fill=color.background,
color=color.background)) +
theme(panel.border     = element_rect(color=color.background)) +
theme(strip.background = element_rect(fill=color.background,
color=color.background)) +

# Format the grid
theme(panel.grid.major.y = element_blank()) +
theme(panel.grid.minor.y = element_blank()) +
theme(axis.ticks       = element_blank()) +

# Format the legend
theme(legend.position = "none") +

# Format title and axis labels
theme(plot.title       = element_text(color=color.text, size=20, face = "bold")) +
theme(axis.title.x     = element_text(size=14, color="black", face = "bold")) +
theme(axis.title.y     = element_text(size=14, color="black", face = "bold",
vjust=1.25)) +
theme(axis.text.x      = element_text(size=10, vjust=0.5, hjust=0.5,
color = color.text)) +
theme(axis.text.y      = element_text(size=10, color = color.text)) +
theme(strip.text       = element_text(face = "bold")) +

# Plot margins
theme(plot.margin = unit(c(0.35, 0.2, 0.3, 0.35), "cm"))
}```

We’ll create the bump chart again, but this time we’ll remove the legend, add some chart labels, and use the theme defined in the code above:

```ggplot(data, aes(x = as.factor(day), y = rank, group = team)) +
geom_line(aes(color = team, alpha = 1), size = 2) +
geom_point(aes(color = team, alpha = 1), size = 4) +
geom_point(color = "#FFFFFF", size = 1) +
scale_y_reverse(breaks = 1:nrow(data)) +
scale_x_discrete(breaks = 1:10) +
theme(legend.position = 'none') +
geom_text(data = data %>% filter(day == "1"),
aes(label = team, x = 0.5) , hjust = .5,
fontface = "bold", color = "#888888", size = 4) +
geom_text(data = data %>% filter(day == "10"),
aes(label = team, x = 10.5) , hjust = 0.5,
fontface = "bold", color = "#888888", size = 4) +
labs(x = 'Day', y = 'Rank', title = 'Team Ranking by Day') +
my_theme() ``` We can also easily highlight one of the lines by adding a scale_color_manual() argument. For example, in the following code we make the line for team A purple and the line for all of the other lines grey:

```ggplot(data, aes(x = as.factor(day), y = rank, group = team)) +
geom_line(aes(color = team, alpha = 1), size = 2) +
geom_point(aes(color = team, alpha = 1), size = 4) +
geom_point(color = "#FFFFFF", size = 1) +
scale_y_reverse(breaks = 1:nrow(data)) +
scale_x_discrete(breaks = 1:10) +
theme(legend.position = 'none') +
geom_text(data = data %>% filter(day == "1"),
aes(label = team, x = 0.5) , hjust = .5,
fontface = "bold", color = "#888888", size = 4) +
geom_text(data = data %>% filter(day == "10"),
aes(label = team, x = 10.5) , hjust = 0.5,
fontface = "bold", color = "#888888", size = 4) +
labs(x = 'Day', y = 'Rank', title = 'Team Ranking by Day') +
my_theme() +
scale_color_manual(values = c('purple', 'grey', 'grey', 'grey', 'grey'))``` We could also highlight more than one line if we’d like:

```ggplot(data, aes(x = as.factor(day), y = rank, group = team)) +
geom_line(aes(color = team, alpha = 1), size = 2) +
geom_point(aes(color = team, alpha = 1), size = 4) +
geom_point(color = "#FFFFFF", size = 1) +
scale_y_reverse(breaks = 1:nrow(data)) +
scale_x_discrete(breaks = 1:10) +
theme(legend.position = 'none') +
geom_text(data = data %>% filter(day == "1"),
aes(label = team, x = 0.5) , hjust = .5,
fontface = "bold", color = "#888888", size = 4) +
geom_text(data = data %>% filter(day == "10"),
aes(label = team, x = 10.5) , hjust = 0.5,
fontface = "bold", color = "#888888", size = 4) +
labs(x = 'Day', y = 'Rank', title = 'Team Ranking by Day') +
my_theme() +
scale_color_manual(values = c('purple', 'steelblue', 'grey', 'grey', 'grey'))``` 