Chapter section list

9.1 Introduction

Besides absolute score values the RWB dataset has also included information about the ranks of the different countries. This wouldn’t be necessary as one could compute from the score values the relative country position. But traditionally the ranks are the most important parameter to compare the different countries. The rank is the only value that is available for all years, starting with the first year 2002 of the World Press Freedom Index (WPFI).

Measured parameters and methodology has changed during 2002 several times, so that there is no comparison possible of the calculated abolute values for all years. The only parameter that was constant over all the years is the rank of the countries, their relative position in a field of currently 180 evaluated countries. The index started 2002 with 139 countries, reached 180 in 2014 and remained constant until today (2025).

R Code 9.1 : Number of countries evaluated per year for the World Press Freedom Index (WPFI)

Code
rwb <- readRDS(paste0(here::here(), "/data/chap011/rwb/rwb.rds"))

rwb |> dplyr::count(year_n) |> 
  print(n = Inf)
Table 9.1: Number of countries evaluated per year for the World Press Freedom Index (WPFI)
#> # A tibble: 23 × 2
#>    year_n     n
#>     <dbl> <int>
#>  1   2002   139
#>  2   2003   166
#>  3   2004   167
#>  4   2005   167
#>  5   2006   168
#>  6   2007   169
#>  7   2008   173
#>  8   2009   175
#>  9   2010   178
#> 10   2012   179
#> 11   2013   179
#> 12   2014   180
#> 13   2015   180
#> 14   2016   180
#> 15   2017   180
#> 16   2018   180
#> 17   2019   180
#> 18   2020   180
#> 19   2021   180
#> 20   2022   180
#> 21   2023   180
#> 22   2024   180
#> 23   2025   180

9.2 Structure of Bump Charts

It is possible to use the normal line chart to display the ranking developments of several countries as I have done as an experiment for the World Happiness Report (WHR) in Rank changes for Countries in Western Europe 2011-2024. The only adaption of the line chart was to reserve the scale so that the lowest figures (= the best rankings) are at the top of the graphic.

But it turned out, that with {ggbump} there is a special R packages for ranking charts. It creates a ggplot() that makes a smooth rank over time. Bump charts are not only good to use to plot ranking over time, but can also be used when the path between two nodes have no statistical significance.

It is typical of bump charts that

  • they have points over the lines,
  • no legends but
  • texts on the vertical sides of the plot to display the change in the rankings.

Two contrasts:

  • In contrast to line charts, or connected scatterplots which show the evolution of the absolute values over time, bump charts indicate the changes in the relative position of the evaluated categories.
  • In contrast to a sorted lollipop chart which also contains a numerical variable and a categorical variable and shows the ranking situation through a comoarison of their length representing the absolute value in a given moment (year), bump charts show the changes in the relative position of the categories over time.
Important 9.1: Bump charts only available in {ggplot2}

As the drawing of bump charts needs {ggbump}, a program of the {ggplot2} universe, I can’t use the native plotly::plot_ly() approach but have to use plotly::ggplotly().

Resource 9.1 : Bump Chart

After a short internet research I found the following resources on bump charts. I have ordered it from the easiest illustration with imaginary data to the more complex examples with real data:

  • Bump chart in {ggplot2} with {ggbump}: This is very nice step-by-step tutorial with imaginary data. It starts by
    • the most basic bump chart, then
    • it is adding points and
    • colors and finally
    • it is adding the texts on the vertical sides of the plot to display the change in the rankings. -Bump chart with {ggplot2}: This page with imaginary does not mention the {ggbump} package but it explains some basci techniques for bump charts as ggplot2::scale_y_reverse() and adding chart labels.
  • R-Graph Gallery has four articles with increasing complexity on bump charts:
    • Basic bump plot explains how to build a basic bump plot with R. It uses the {ggbump} package, provides reproducible code and explains how input data must be formatted.
    • Create bumbplot with ggbump is another basic introduction with has collected at the end some links of bump chart examples.
    • Customized bump plot explains how to change colors, and adding labels and title.
    • Bump plot with highlights is the most complex article. It shows
      • how to change the order and adding individual points
      • how to change the theme and adding annotations
  • Bump it Up: Creating a Bump Chart in R: Provides a nice but complex example with
    • data exploration,
    • data pre-processing,
    • adding image data (logoi of the soccer clubs, but could be in my use case country flags)
    • basic plot
    • scales & labels
    • finishing touches
  • Bump Chart: Track performance over time: A complex article that demonstrates the power of bump charts with data from the 2018 Olympic Winter Games in PyeongChang.
  • ggbump repo: It is the GitHub repository for the {ggbump} package. The README has some examples but — with the exception of the first illustration — they are all very complex and not suitable for step-by-step introduction or tutorial. The code for the first example is partly taken from the package online help but has additonal features not documented with code.

Step-by-Step Guide for Building Bump Charts in Plotly: This article is written for Python and is therefore not direct applicable for my R coding. But it shows some interesting new ideas that are not contained in the above R code examples:

  • Comparing the rankings for only two years with straight lines. It has the effect that it is much easier to follow the lines and detect the differences. The graphics needs therefore only labels of the right side of the figure. Besides this kind of bump chart would not need the {ggbump} package.
  • Adjusting the marker size in relation to the absolute value of the measure taken for the ranking. This is an interesting feature that shows not only the change in the ranks but also in the values.
  • Adding the rank number inside the markers. This saves space and would not need a Y axis any more.

9.3 Bump Chart Step-by-Step

For a demonstration of bump charts I will take as data the top ten RWB countries form 2025.

R Code 9.2 : Data frame of the top ten RWB countries

Code
rwb <- readRDS(paste0(here::here(), "/data/chap011/rwb/rwb.rds"))

vec_top_ten_2025 <- rwb |> 
  dplyr::filter(year_n == 2025) |> 
  dplyr::arrange(rank) |> 
  dplyr::slice_head(n = 10) |> 
  dplyr::pull(country_en) |> 
  as.character()

vec_top_ten_2025
Code
my_save_data_file("chap091", vec_top_ten_2025, "vec_top_ten_2025.rds")
Table 9.2: Vector list of the 10 countries with the best WPF Index in 2025
#>  [1] "Norway"      "Estonia"     "Netherlands" "Sweden"      "Finland"    
#>  [6] "Denmark"     "Ireland"     "Portugal"    "Switzerland" "Czechia"

9.3.1 Most basic bump chart

R Code 9.3 : Evolution of the rankings of the top ten countries in 2025

Code
library(dplyr, warn.conflicts = FALSE)
library(ggplot2)
library(ggbump)

# select top ten countries of 2025
rwb_top_ten <- rwb |> 
  dplyr::filter(country_en %in% vec_top_ten_2025)


p <- ggplot(rwb_top_ten, 
       aes(x = year_n, 
           y = rank, 
           color = country_en)) +
  geom_bump()

plotly::ggplotly(p)
Graph 9.1: Evolution of the rankings of the top ten countries in 2025

9.4 Glossary Entries

term definition
RWB Reporters Without Borders (RWB), known by its French name Reporters sans frontières and acronym RSF, is an international non-profit and non-governmental organization headquartered in Paris, France, founded in 1985 in Montpellier by journalists Robert Ménard, Rémy Loury, Jacques Molénat, and Émilien Jubineau. It is dedicated to safeguarding the right to freedom of information and defends journalists and media personnel who are imprisoned, persecuted, or at risk for their work. The organization has consultative status at the United Nations, UNESCO, the Council of Europe, and the International Organisation of the Francophonie.
WHR The World Happiness Reports are a partnership of Gallup, the Oxford Wellbeing Research Centre, the UN Sustainable Development Solutions Network, and the WHR’s Editorial Board. The report is produced under the editorial control of the WHR Editorial Board. The Reports reflects a worldwide demand for more attention to happiness and well-being as criteria for government policy. It reviews the state of happiness in the world today and shows how the science of happiness explains personal and national variations in happiness. (https://worldhappiness.report/about/)

Session Info

Session Info

Code
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.5.1 (2025-06-13)
#>  os       macOS Sequoia 15.6.1
#>  system   aarch64, darwin20
#>  ui       X11
#>  language (EN)
#>  collate  en_US.UTF-8
#>  ctype    en_US.UTF-8
#>  tz       Europe/Zagreb
#>  date     2025-09-25
#>  pandoc   3.7.0.2 @ /opt/homebrew/bin/ (via rmarkdown)
#>  quarto   1.8.4 @ /usr/local/bin/quarto
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package      * version    date (UTC) lib source
#>  cli            3.6.5      2025-04-23 [1] CRAN (R 4.5.0)
#>  commonmark     2.0.0      2025-07-07 [1] CRAN (R 4.5.0)
#>  crosstalk      1.2.2      2025-08-26 [1] CRAN (R 4.5.0)
#>  curl           7.0.0      2025-08-19 [1] CRAN (R 4.5.0)
#>  data.table     1.17.8     2025-07-10 [1] CRAN (R 4.5.0)
#>  dichromat      2.0-0.1    2022-05-02 [1] CRAN (R 4.5.0)
#>  digest         0.6.37     2024-08-19 [1] CRAN (R 4.5.0)
#>  dplyr        * 1.1.4      2023-11-17 [1] CRAN (R 4.5.0)
#>  evaluate       1.0.5      2025-08-27 [1] CRAN (R 4.5.1)
#>  farver         2.1.2      2024-05-13 [1] CRAN (R 4.5.0)
#>  fastmap        1.2.0      2024-05-15 [1] CRAN (R 4.5.0)
#>  generics       0.1.4      2025-05-09 [1] CRAN (R 4.5.0)
#>  ggbump       * 0.1.0      2020-04-24 [1] CRAN (R 4.5.0)
#>  ggplot2      * 4.0.0      2025-09-11 [1] CRAN (R 4.5.0)
#>  glossary     * 1.0.0.9003 2025-06-08 [1] local
#>  glue           1.8.0      2024-09-30 [1] CRAN (R 4.5.0)
#>  gtable         0.3.6      2024-10-25 [1] CRAN (R 4.5.0)
#>  here           1.0.2      2025-09-15 [1] CRAN (R 4.5.0)
#>  htmltools      0.5.8.1    2024-04-04 [1] CRAN (R 4.5.0)
#>  htmlwidgets    1.6.4      2023-12-06 [1] CRAN (R 4.5.0)
#>  httr           1.4.7      2023-08-15 [1] CRAN (R 4.5.0)
#>  jsonlite       2.0.0      2025-03-27 [1] CRAN (R 4.5.0)
#>  kableExtra     1.4.0      2024-01-24 [1] CRAN (R 4.5.0)
#>  knitr          1.50       2025-03-16 [1] CRAN (R 4.5.0)
#>  labeling       0.4.3      2023-08-29 [1] CRAN (R 4.5.0)
#>  lazyeval       0.2.2      2019-03-15 [1] CRAN (R 4.5.0)
#>  lifecycle      1.0.4      2023-11-07 [1] CRAN (R 4.5.0)
#>  litedown       0.7        2025-04-08 [1] CRAN (R 4.5.0)
#>  magrittr       2.0.4      2025-09-12 [1] CRAN (R 4.5.0)
#>  markdown       2.0        2025-03-23 [1] CRAN (R 4.5.0)
#>  pillar         1.11.1     2025-09-17 [1] CRAN (R 4.5.0)
#>  pkgconfig      2.0.3      2019-09-22 [1] CRAN (R 4.5.0)
#>  plotly       * 4.11.0     2025-06-19 [1] CRAN (R 4.5.0)
#>  purrr          1.1.0      2025-07-10 [1] CRAN (R 4.5.0)
#>  R6             2.6.1      2025-02-15 [1] CRAN (R 4.5.0)
#>  RColorBrewer   1.1-3      2022-04-03 [1] CRAN (R 4.5.0)
#>  rlang          1.1.6      2025-04-11 [1] CRAN (R 4.5.0)
#>  rmarkdown      2.29       2024-11-04 [1] CRAN (R 4.5.0)
#>  rprojroot      2.1.1      2025-08-26 [1] CRAN (R 4.5.0)
#>  rstudioapi     0.17.1     2024-10-22 [1] CRAN (R 4.5.0)
#>  rversions      2.1.2      2022-08-31 [1] CRAN (R 4.5.0)
#>  S7             0.2.0      2024-11-07 [1] CRAN (R 4.5.0)
#>  scales         1.4.0      2025-04-24 [1] CRAN (R 4.5.0)
#>  sessioninfo    1.2.3      2025-02-05 [1] CRAN (R 4.5.0)
#>  stringi        1.8.7      2025-03-27 [1] CRAN (R 4.5.0)
#>  stringr        1.5.2      2025-09-08 [1] CRAN (R 4.5.0)
#>  svglite        2.2.1      2025-05-12 [1] CRAN (R 4.5.0)
#>  systemfonts    1.2.3      2025-04-30 [1] CRAN (R 4.5.0)
#>  textshaping    1.0.3      2025-09-02 [1] CRAN (R 4.5.0)
#>  tibble         3.3.0      2025-06-08 [1] CRAN (R 4.5.0)
#>  tidyr          1.3.1      2024-01-24 [1] CRAN (R 4.5.0)
#>  tidyselect     1.2.1      2024-03-11 [1] CRAN (R 4.5.0)
#>  vctrs          0.6.5      2023-12-01 [1] CRAN (R 4.5.0)
#>  viridisLite    0.4.2      2023-05-02 [1] CRAN (R 4.5.0)
#>  withr          3.0.2      2024-10-28 [1] CRAN (R 4.5.0)
#>  xfun           0.53       2025-08-19 [1] CRAN (R 4.5.0)
#>  xml2           1.4.0      2025-08-20 [1] CRAN (R 4.5.0)
#>  yaml           2.3.10     2024-07-26 [1] CRAN (R 4.5.0)
#> 
#>  [1] /Library/Frameworks/R.framework/Versions/4.5-arm64/library
#>  [2] /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/library
#>  * ── Packages attached to the search path.
#> 
#> ──────────────────────────────────────────────────────────────────────────────