line chart
social
Author

Ana Luisa Bodevan

Published

October 14, 2025

Code
# TidyTuesday 2025-10-14 - World Food Day

# 1. SETUP ------------------------------------------------------

library(pacman)
pacman::p_load(tidyverse, tidytuesdayR, dplyr, showtext, ggtext, scales)

tuesdata <- tidytuesdayR::tt_load('2025-10-14')
df <- tuesdata[[1]] |> 
  rename_all(tolower)

# 2. DATA WRANGLING -----------------------------------------------

# Food insecurity by biological sex and world region 

plot <- df %>%
  select(year = year_end, area, item, value) %>%
  filter(
    item %in% c(
      "Prevalence of moderate or severe food insecurity in the female adult population (percent) (annual value)",
      "Prevalence of moderate or severe food insecurity in the male adult population (percent) (annual value)"
    )
  ) %>%
  mutate(
    region = case_when(
      area %in% c("South America", "Central America") ~ "Latin America",
      TRUE ~ area
    ),
    sex = case_when(
      str_detect(item, "female") ~ "Female",
      str_detect(item, "male") ~ "Male"
    )
  ) %>%
  filter(region %in% c("Africa", "Asia", "Europe", "Northern America", "Oceania", "Latin America")) %>%
  group_by(year, region, sex) %>%
  summarize(value = mean(value, na.rm = TRUE), .groups = "drop")

# Filter for Latin America
plot_latam <- plot %>%
  filter(region == "Latin America") %>%
  pivot_wider(names_from = sex, values_from = value) %>%
  mutate(gap = Female - Male)

# Create base data for lines
plot_latam_long <- plot %>%
  filter(region == "Latin America")

# 4. PLOT ---------------------------------------------------------

# Font
font <- "Lato"
font_add_google(font, regular.wt = 400, bold.wt = 700)
showtext_auto()
showtext_opts(dpi = 300)

# Colors
bg <- "white" # background color
text <- "black" # text color
pal <- c("Female" = "#bfa5be", "Male" = "#73B092") 

ggplot() +
  # Ribbon showing the gap
  geom_ribbon(
    data = plot_latam,
    aes(x = year, ymin = Male, ymax = Female),
    fill = "#eaeff2ff",
    alpha = 0.6
  ) +
 
  # Lines for each sex
  geom_line(
    data = plot_latam_long,
    aes(x = year, y = value, color = sex),
    linewidth = 1.5
  ) +
  geom_point(
    data = plot_latam_long,
    aes(x = year, y = value, color = sex),
    size = 2.5
  ) +
 
  scale_color_manual(values = pal) +
  scale_y_continuous(
    limits = c(0, NA),
    breaks = seq(0, 40, 10),
    expand = expansion(mult = c(0, 0.05))
  ) +
  scale_x_continuous(
    breaks = seq(min(plot_latam_long$year), max(plot_latam_long$year), 2)
  ) +
 
  labs(
    title = "Gender Gap in Food Insecurity Persists in Latin America",
    subtitle = "Proportion of females and males facing severe or moderate food insecurity (%)",
    x = NULL,
    y = NULL,
    color = NULL,
    caption = "Source: FAO | Shaded area represents the gender gap | @anabodevan #TidyTuesday"
  ) +
 
  theme_minimal(base_family = font, base_size = 16) +
  theme(
    plot.background = element_rect(fill = bg, color = NA),
    panel.background = element_rect(fill = bg, color = NA),
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    
    # Fix legend
    legend.position = "top",
    legend.justification = "left",
    legend.direction = "vertical",
    legend.text = element_text(size = 7, color = text, margin = margin(r = 15)),
    legend.key.size = unit(1.2, "cm"),
    legend.margin = margin(b = 10),
    
    # Fix axis
    axis.text.y = element_text(size = 7, color = text, margin = margin(r = 8)),
    axis.text.x = element_text(size = 7, color = text, margin = margin(t = 8)),
    axis.title.y = element_text(size = 7, color = text, margin = margin(r = 12)),
    
    # Fix titles
    plot.title = element_text(face = "bold", size = 10, color = text, margin = margin(b = 8, t = 10)),
    plot.subtitle = element_text(color = text, size = 8, margin = margin(b = 25), lineheight = 1.2),
    plot.caption = element_text(color = "#666666", size = 6, hjust = 0, margin = margin(t = 35)),
    plot.caption.position = "plot",
    plot.title.position = "plot",
    
    
    plot.margin = margin(30, 50, 30, 30)
  )