Flags of Change: Global Governance Through the Decades
This visualization tracks the global transformation of political regimes from 1950 to 2020, showcasing the decline of colonial and military rule and the steady rise of democracies. Despite these shifts, civilian dictatorships continue to maintain a strong presence.
#TidyTuesday
Governance
{ggflags}
Author
Aditya Dahiya
Published
November 6, 2024
The Democracy and Dictatorship dataset is an extensive compilation that examines political regimes worldwide from 1950 to 2020. It is an updated version of the PACL dataset, incorporating a broader set of countries. The dataset provides detailed information on various regime types, transitions between democracies and autocracies, and related political institutions. It is based on the research of C. Bjørnskov and M. Rode, as discussed in The Review of International Organizations (2020) (Bjørnskov and Rode 2019). The full dataset and its codebook are accessible for download here. This data is ideal for exploring historical regime changes and their characteristics, such as elections, regime types, and leaders.
How I made this graphic?
Loading required libraries, data import & creating custom functions.
Code
# Data Import and Wrangling Toolslibrary(tidyverse) # All things tidy# Final plot toolslibrary(scales) # Nice Scales for ggplot2library(fontawesome) # Icons display in ggplot2library(ggtext) # Markdown text support for ggplot2library(showtext) # Display fonts in ggplot2library(colorspace) # Lighten and Darken coloursdemocracy_data <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2024/2024-11-05/democracy_data.csv')
Visualization Parameters
Code
# Font for titlesfont_add_google("Saira",family ="title_font") # Font for the captionfont_add_google("Saira Extra Condensed",family ="caption_font") # Font for plot textfont_add_google("Saira Condensed",family ="body_font") showtext_auto()# A base Colourbase_col <-"white"bg_col <-darken(base_col, 0.2)seecolor::print_color(bg_col)# Colour for the texttext_col <-darken(bg_col, 0.9)seecolor::print_color(text_col)# Colour for highlighted texttext_hil <-darken(bg_col, 0.7)seecolor::print_color(text_hil)# Define Base Text Sizebts <-90# Caption stuff for the plotsysfonts::font_add(family ="Font Awesome 6 Brands",regular = here::here("docs", "Font Awesome 6 Brands-Regular-400.otf"))github <-""github_username <-"aditya-dahiya"xtwitter <-""xtwitter_username <-"@adityadahiyaias"social_caption_1 <- glue::glue("<span style='font-family:\"Font Awesome 6 Brands\";'>{github};</span> <span style='color: {text_hil}'>{github_username} </span>")social_caption_2 <- glue::glue("<span style='font-family:\"Font Awesome 6 Brands\";'>{xtwitter};</span> <span style='color: {text_hil}'>{xtwitter_username}</span>")# Add text to plot--------------------------------------------------------------plot_title <-"Regimes Transformed: 1950 - 2020"plot_subtitle <-str_wrap("Over the past seven decades, the number of democracies worldwide has notably increased, with colonies nearly disappearing by 1980 and a decline in military dictatorships by 2020. However, civilian dictatorships remain prevalent despite this progress.", 130)plot_caption <-paste0("**Data:** Bjørnskov and Rode (2020): PACL dataset", " | **Code:** ", social_caption_1, " | **Graphics:** ", social_caption_2 )rm(github, github_username, xtwitter, xtwitter_username, social_caption_1, social_caption_2)
Exploratory Data Analysis and Wrangling
Code
democracy_data |> summarytools::dfSummary() |> summarytools::view()df <- democracy_data |>count(regime_category) |>mutate(regime_category =case_when(str_detect(regime_category, "Colony|colony|British") ~"Colony",str_detect(regime_category, "Royal dictatorship") ~"Civilian dictatorship",.default = regime_category ) ) |>count(regime_category, wt = n, sort = T) |>slice_max(order_by = n, n =6) |>mutate(regime_category =fct( regime_category,levels =c("Colony","Civilian dictatorship","Military dictatorship","Presidential democracy","Parliamentary democracy","Mixed democratic" ) ) )levels_regime <-c("Colony","Civilian dictatorship","Military dictatorship","Presidential democracy","Parliamentary democracy","Mixed democratic" )plotdf <- democracy_data |>mutate(regime_category =case_when(str_detect(regime_category, "Colony|colony|British") ~"Colony",str_detect(regime_category, "Royal dictatorship") ~"Civilian dictatorship",.default = regime_category ) ) |>filter(regime_category %in% levels_regime) |>mutate(regime_category =fct(regime_category, levels = levels_regime))plotdf |>filter(year %in%c(1950, 1985, 2020)) |>count(year, regime_category) |>ggplot(aes(x = year, y = n, fill = regime_category)) +geom_col(position ="fill" )plotdf |>filter(year %in%c(1950, 1985, 2020)) |>mutate(year =as_factor(year)) |>ggplot(mapping =aes(x = year,y = regime_category ) ) +geom_point(position = ggbeeswarm::position_beeswarm(method ="hex",cex =2,corral ="wrap" ) )# Lets manually create the hex jitter we need# The base data we will needdf2 <- plotdf |>filter(year %in%c(1950, 1980, 2020)) |>mutate(year =case_when( year ==1950~1, year ==1980~2, year ==2020~3,.default =NA ) ) |>left_join(tibble(regime_category = levels_regime,regime_val =1:6 ) ) |>select(country_code, year, regime_val) |>mutate(country_code = countrycode::countrycode( country_code,origin ="iso3c",destination ="iso2c" ),country_code =str_to_lower(country_code) ) |>filter(country_code %in%names(ggflags::lflags))# Labels for x and y axisx_axis_labels <-c(1950, 1980, 2020)y_axis_labels <- levels_regimex_axis_labelsy_axis_labelsnumber_of_rows <- df2 |>count(year, regime_val) |>mutate(number_rows = (n %/%10) +1) |>select(-n)horizontal_gaps <-seq(from =-0.4, to =+0.4, length.out =10)round(horizontal_gaps, 2)vertical_gaps <-seq(from =-0.4, to =+0.4, length.out =8)round(vertical_gaps, 2)# Manually creating the jitter and flag spacing for each flag positionfinal_plot_df <- df2 |>left_join(number_of_rows) |>arrange(year, regime_val) |>group_by(year, regime_val) |>mutate(id =row_number()) |>mutate(each_row_value =case_when( id <=10~1, (id >10& id <=20) ~-1, (id >20& id <=30) ~2, (id >30& id <=40) ~-2, (id >40& id <=50) ~3, (id >50& id <=60) ~-3, (id >60& id <=70) ~4, (id >70& id <=80) ~-4,.default =NA ) ) |>group_by(year, regime_val, each_row_value) |>mutate(row_id =row_number()) |>mutate(x_var =case_when( row_id ==1~ year + horizontal_gaps[5], row_id ==2~ year + horizontal_gaps[6], row_id ==3~ year + horizontal_gaps[4], row_id ==4~ year + horizontal_gaps[7], row_id ==5~ year + horizontal_gaps[3], row_id ==6~ year + horizontal_gaps[8], row_id ==7~ year + horizontal_gaps[2], row_id ==8~ year + horizontal_gaps[9], row_id ==9~ year + horizontal_gaps[1], row_id ==10~ year + horizontal_gaps[10],.default =NA ) ) |>mutate(y_var =case_when( each_row_value ==1~ regime_val + vertical_gaps[4], each_row_value ==-1~ regime_val + vertical_gaps[5], each_row_value ==2~ regime_val + vertical_gaps[3], each_row_value ==-2~ regime_val + vertical_gaps[6], each_row_value ==3~ regime_val + vertical_gaps[2], each_row_value ==-3~ regime_val + vertical_gaps[7], each_row_value ==4~ regime_val + vertical_gaps[1], each_row_value ==-4~ regime_val + vertical_gaps[8],.default =NA ) ) |>mutate(country_name = countrycode::countrycode(sourcevar =str_to_upper(country_code),origin ="iso2c",destination ="country.name" ) ) # A tibble to label the total number of countries in each groupplot_labels_df <- df2 |>count(regime_val, year) |>mutate(x_var = year,y_var =case_when( (regime_val ==1& year ==1) ~ regime_val +0.6, (regime_val ==2& year ==1) ~ regime_val +0.4, (regime_val ==6& year ==1) ~ regime_val +0.2, (regime_val ==2& year ==2) ~ regime_val +0.5, (regime_val ==3& year ==2) ~ regime_val +0.4, (regime_val ==5& year ==2) ~ regime_val +0.4, (regime_val ==6& year ==2) ~ regime_val +0.2, (regime_val ==2& year ==3) ~ regime_val +0.5, (regime_val ==5& year ==3) ~ regime_val +0.4, (regime_val ==1& year ==3) ~ regime_val +0.2,.default = regime_val +0.3 ) )
# Saving a thumbnaillibrary(magick)# Saving a thumbnail for the webpageimage_read(here::here("data_vizs", "tidy_democracy_data.png")) |>image_resize(geometry ="400") |>image_write( here::here("data_vizs", "thumbnails", "tidy_democracy_data.png" ) )
Session Info
Code
# Data Import and Wrangling Toolslibrary(tidyverse) # All things tidy# Final plot toolslibrary(scales) # Nice Scales for ggplot2library(fontawesome) # Icons display in ggplot2library(ggtext) # Markdown text support for ggplot2library(showtext) # Display fonts in ggplot2library(colorspace) # Lighten and Darken colourssessioninfo::session_info()$packages |>as_tibble() |>select(package, version = loadedversion, date, source) |>arrange(package) |> janitor::clean_names(case ="title" ) |> gt::gt() |> gt::opt_interactive(use_search =TRUE ) |> gtExtras::gt_theme_espn()
References
Bjørnskov, Christian, and Martin Rode. 2019. “Regime Types and Regime Change: A New Dataset on Democracy, Coups, and Political Institutions.”The Review of International Organizations 15 (2): 531–51. https://doi.org/10.1007/s11558-019-09345-1.