World’s Fairs data @ #TidyTuesday

Which months of the years were the World Expos and Specialized Expos held in the last 150 years

#TidyTuesday
Author

Aditya Dahiya

Published

August 14, 2024

Figure 1: A line-segment chart showing the months in which the World Expos and Specialized Expos were held, and the length of each. On X-axis are the months, and on Y-axis are the Years.

How I made this graphic?

Loading libraries & data

Code
# Data Import and Wrangling Tools
library(tidyverse)            # All things tidy

# Final plot tools
library(scales)               # Nice Scales for ggplot2
library(fontawesome)          # Icons display in ggplot2
library(ggtext)               # Markdown text support for ggplot2
library(showtext)             # Display fonts in ggplot2
library(colorspace)           # Lighten and Darken colours
library(seecolor)             # To print and view colours
library(patchwork)            # Combining plots

# Read data directly from GitHub
worlds_fairs <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2024/2024-08-13/worlds_fairs.csv')

Data Wrangling

Code
# worlds_fairs |> 
#   summarytools::dfSummary() |> 
#   summarytools::view()
# 
# worlds_fairs |> 
#   group_by(category) |> 
#   summarise(mean(is.na(cost)))

df <- worlds_fairs |> 
  mutate(
    end_month = if_else(
      start_year != end_year,
      12 + end_month,
      end_month
    ),
    end_year = if_else(
      start_year != end_year,
      start_year,
      end_year
    )
  ) |> 
  filter(!((start_month == end_month) & (start_year == end_year)))

df_year <- df |> distinct(start_year)

Visualization Parameters

Code
# Font for titles
font_add_google("Amita",
  family = "title_font"
) 

# Font for the caption
font_add_google("Saira Extra Condensed",
  family = "caption_font"
) 

# Font for plot text
font_add_google("Ubuntu Condensed",
  family = "body_font"
) 

showtext_auto()

mypal <- paletteer::paletteer_d("nbapalettes::clippers_original")
mypal
text_col <- "grey30"
text_hil <- "grey30"

bts <- 80

# Caption stuff for the plot
sysfonts::font_add(
  family = "Font Awesome 6 Brands",
  regular = here::here("docs", "Font Awesome 6 Brands-Regular-400.otf")
)
github <- "&#xf09b"
github_username <- "aditya-dahiya"
xtwitter <- "&#xe61b"
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>")

plot_title <- "World Expositions"

plot_subtitle <- glue::glue("BIE-sanctioned World Expositions, known<br>for their extensive scope, typically<br>occur from *April to November*, aligning<br>with favorable weather conditions. From<br>1970s to 1990s, there were far more<br><b style='color:{mypal[1]}'>Specialized Expo</b>, than <b style='color:{mypal[3]}'>World Expos</b>.")
str_view(plot_subtitle)

plot_caption <- paste0(
  "**Data:** Wikipedia & Bureau International des Expositions", 
  " |  **Code:** ", 
  social_caption_1, 
  " |  **Graphics:** ", 
  social_caption_2
  )

rm(github, github_username, xtwitter, 
   xtwitter_username, social_caption_1, 
   social_caption_2)

The static plot

Code
g <- df |> 
  
  # Start Plot
  ggplot(
    mapping = aes(
      y = start_year
    )
  ) +
  
  # Segment Lines to plot data
  geom_segment(
    mapping = aes(
      yend = start_year,
      x = start_month,
      xend = end_month,
      colour = category
    ),
    alpha = 0.95,
    linewidth = 2.5
  ) +
  # Text labels within the segments
  geom_text(
    mapping = aes(
      x = start_month,
      label = paste0(city, ", ", country, ": ", name_of_exposition)
    ),
    family = "caption_font",
    size = bts / 20,
    colour = "grey10",
    hjust = 0,
    nudge_x = 0.05,
    vjust = 0.5
  ) +
  
  # Bottom X-axis
  geom_text(
    data = df_year,
    mapping = aes(
      x = 1,
      label = start_year
    ),
    hjust = 1,
    colour = text_hil,
    size = bts / 12
  ) +
  geom_text(
    data = tibble(
      x_var = 1:22, 
      label_var = c(month.abb, month.abb[1:10])
    ),
    mapping = aes(
      x = x_var,
      y = 1845,
      label = label_var
    ),
    family = "body_font",
    colour = text_col,
    size = bts / 3
  ) +
  annotate(
    geom = "segment",
    x = 1, xend = 12.4, y = 1840, yend = 1840,
    arrow = arrow(length = unit(5, "mm"), angle = 90, ends = "both"),
    colour = text_col
  ) +
  annotate(
    geom = "segment",
    x = 12.6, xend = 21.9, y = 1840, yend = 1840,
    arrow = arrow(length = unit(5, "mm"), angle = 90, ends = "both"),
    colour = text_col
  ) +
  annotate(
    geom = "text",
    y = 1839, x = 6.5,
    label = "Months of the Expo Year",
    hjust = 0.5,
    vjust = 1,
    colour = text_col,
    family = "body_font",
    size = bts / 2
  ) +
  annotate(
    geom = "text",
    y = 1839, x = 17,
    label = "Next Year's months",
    hjust = 0.5,
    vjust = 1,
    colour = text_col,
    family = "body_font",
    size = bts / 2
  ) +
  
  # Plot Subtitle as an annotation on the plot
  annotate(
    geom = "richtext",
    y = 2015, x = 21.5,
    label = plot_subtitle,
    hjust = 1,
    vjust = 1,
    colour = text_hil,
    family = "body_font",
    size = bts / 2.5,
    lineheight = 0.35,
    label.size = NA
  ) +
  
  # Scales and Coordinates
  scale_x_continuous(
    expand = expansion(0),
    breaks = 1:22,
    limits = c(0.9, 22)
  ) +
  scale_y_continuous(
    limits = c(1835, 2024)
  ) +
  scale_colour_manual(
    values = c(mypal[1], mypal[3])
  ) +
  scale_linewidth_continuous(
    range = c(2, 12)
  ) +
  guides(
    colour = "none"
  ) +
  coord_cartesian(
    clip = "off"
  ) +
  
  # Labels and Themes
  labs(
    title = plot_title,
    # subtitle = plot_subtitle,
    caption = plot_caption,
    colour = "Expo Category",
    y = "Year of the Exposition",
    x = NULL,
    linewidth = "Number of Visitors\nat Expo (millions)"
  ) +
  theme_minimal(
    base_family = "body_font",
    base_size = bts * 1.2
  ) +
  theme(
    plot.title.position = "plot",
    plot.margin = margin(10,10,10,10, "mm"),
    legend.position = c(0.8, 0.2),
    text = element_text(
      colour = text_col,
      family = "body_font",
      margin = margin(0,0,0,0, "mm"),
      lineheight = 0.3
    ),
    plot.title = element_text(
      hjust = 0.5,
      size = 5 * bts,
      margin = margin(10,0,0,0, "mm"),
      family = "title_font"
    ),
    plot.caption = element_textbox(
      hjust = 0.5,
      family = "caption_font",
      margin = margin(0,0,10,0, "mm")
    ),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    panel.grid.minor.x = element_blank(),
    panel.grid.major.x = element_blank(),
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.length = unit(0, "mm"),
    legend.title = element_text(
      lineheight = 0.35,
      colour = text_col
    )
  )

Savings the graphics

Code
ggsave(
  filename = here::here("data_vizs", "tidy_world_fairs.png"),
  plot = g,
  width = 400,    # Best Twitter Aspect Ratio = 5:4
  height = 500,   
  units = "mm",
  bg = "white"
)

library(magick)
# Saving a thumbnail for the webpage
image_read(here::here("data_vizs", "tidy_world_fairs.png")) |> 
  image_resize(geometry = "400") |> 
  image_write(here::here("data_vizs", "thumbnails", "tidy_world_fairs.png"))