Skip to contents

A bump chart shows how the rank of several entities changes across successive time periods. Each entity is drawn as a smooth line that moves up or down as it overtakes, or is overtaken by, the others, with a circle at every period showing its rank. Popularised by the Financial Times, The Economist and FiveThirtyEight (league tables, election polls, country rankings), it is the clearest way to tell a "who is ahead?" story when the order matters more than the exact values.

The data must be in long format: one row per entity and period. By default the ranks are computed per period from the numeric y column (rank 1 = highest value). Set ranked = TRUE if y already contains the ranks.

Usage

bump_chart(
  data,
  x,
  y,
  group,
  ranked = FALSE,
  rankOrder = "desc",
  colors = NULL,
  highlight = NULL,
  greyCol = "#d3d3d3",
  lineWidth = 3,
  circleRadius = 11,
  showRank = TRUE,
  title = NULL,
  titleFontSize = 16,
  xFontSize = 11,
  labelFontSize = 11,
  font = "Verdana, Geneva, Tahoma, sans-serif",
  bgcol = "white",
  axisCol = "black",
  width = NULL,
  height = NULL
)

Arguments

data

The data frame containing the variables to consider, in long format (one row per group and period).

x

The name of the column holding the time period. Numeric and Date columns are ordered chronologically, factors follow their level order and character columns follow their order of appearance.

y

The name of the numeric column holding the value to rank (or the rank itself when ranked = TRUE).

group

The name of the column identifying each entity (one line per entity). Each group can appear at most once per period.

ranked

Whether y already contains ranks. Defaults to FALSE, in which case ranks are computed per period from y.

rankOrder

How ranks are computed when ranked = FALSE. One of "desc" (default, the highest value gets rank 1) or "asc" (the lowest value gets rank 1). Ties are broken by order of appearance in the data.

colors

Optional. A character vector of colors, recycled across the groups in order of appearance, or a named vector mapping group names to colors. Colors must be valid CSS colors (e.g. "steelblue" or "#1f77b4"); R-only names such as "grey40" are not understood by the browser. Defaults to the D3 Tableau 10 palette.

highlight

Optional. A character vector of group names to highlight. All other groups are drawn in greyCol.

greyCol

Color used for groups that are not highlighted. Defaults to "#d3d3d3".

lineWidth

Width of the lines in pixels. Defaults to 3.

circleRadius

Maximum radius of the circles in pixels. It is reduced automatically when there are many groups or periods. Defaults to 11.

showRank

Whether to print the rank number inside each circle. Defaults to TRUE.

title

Optional. Title of the chart.

titleFontSize

Font size of the chart title. Defaults to 16.

xFontSize

Font size of the period labels on the x-axis. Defaults to 11.

labelFontSize

Font size of the group labels drawn at both ends of each line. Defaults to 11.

font

The font family used for all text. Defaults to "Verdana, Geneva, Tahoma, sans-serif".

bgcol

Background color of the SVG. Defaults to "white".

axisCol

Color of the period labels, grid lines and title. Defaults to "black".

width

Optional. The width of the SVG output.

height

Optional. The height of the SVG output.

Value

An SVG bump chart.

Examples

# Points scored by five teams over four seasons
league <- data.frame(
  season = rep(c("2023", "2024", "2025", "2026"), each = 5),
  team   = rep(c("Lions", "Tigers", "Bears", "Wolves", "Eagles"), 4),
  points = c(80, 75, 60, 55, 50,
             70, 82, 58, 66, 49,
             65, 78, 72, 69, 52,
             60, 74, 81, 70, 77)
)

bump_chart(
  data  = league,
  x     = "season",
  y     = "points",
  group = "team",
  title = "League ranking by season"
)
# GDP per capita rank of the Asian "tiger" economies, highlighting two library(gapminder) countries <- c("Japan", "Singapore", "Hong Kong, China", "Taiwan", "Korea, Rep.", "Malaysia", "Thailand", "China") gdp <- gapminder[gapminder$country %in% countries & gapminder$year >= 1967, ] gdp$country <- as.character(gdp$country) bump_chart( data = gdp, x = "year", y = "gdpPercap", group = "country", highlight = c("Singapore", "Korea, Rep."), title = "GDP per capita rank, 1967-2007" )