Crane Observations at Lake Hornborgasjön, Sweden (1994–2024)

line chart
fauna
Author

Ana Luisa Bodevan

Published

September 30, 2025

Code
# Crane Observations at Lake Hornborgasjön, Sweden (1994–2024)

######## 1. SETUP

rm(list=ls())

library(pacman)
pacman::p_load(tidyverse, ggtext, showtext, ggridges, lubridate, scales, stringr)

cranes <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2025/2025-09-30/cranes.csv')

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

# Add year, day-of-year, and season
cranes_years <- cranes %>%
  filter(year(date) %in% c(2004, 2014, 2024), !is.na(observations)) %>%
  mutate(
    doy = yday(date),
    season = case_when(
      doy >= 60 & doy <= 151  ~ "Spring",
      doy >= 152 & doy <= 243 ~ "Summer",
      doy >= 244 & doy <= 334 ~ "Autumn",
      TRUE                    ~ "Winter"
    )
  )

# Join seasons and observations 
data <- cranes_years %>%
  group_by(year = year(date), season) %>%
  summarise(total_observations = sum(observations, na.rm = TRUE),
            .groups = "drop")

# Base plot 
ggplot(data, aes(x = season, y = total_observations, color = factor(year), group = year)) +
  geom_line(linewidth = 1) +
  geom_point(size = 3) +
  scale_x_discrete(limits = c("Summer", "Autumn", "Spring")) +
  labs(title = "Crane Observations Across Seasons",
       x = "Season",
       y = "Total Observations",
       color = "Year") +
  theme_minimal()

######## 3. PLOT

ggplot(data, aes(x = season, y = total_observations, color = factor(year), group = year)) +
  geom_line(linewidth = 1.5, alpha = 0.9) +
  geom_point(size = 5, alpha = 1) +
  
  scale_x_discrete(limits = c("Summer", "Autumn", "Spring")) +
  scale_y_continuous(labels = scales::comma, trans = "log10") +
  scale_color_manual(values = c("2004" = "#4a5568", "2014" = "#718096", "2024" = "#a0aec0")) +
  
  labs(title = "Cranes of Spring",
       subtitle = "A three-decade-spanning migration pattern at Lake Hornborgasjön, Sweden",
       caption = "Data: Hornborgasjön field station | Viz: @anabodevan | #TidyTuesday",
       x = NULL,
       y = "Observations",
       color = NULL) +
  
  theme_minimal(base_size = 12, base_family = "serif") +
  theme(
    plot.background = element_rect(fill = "#f7fafc", color = NA),
    panel.background = element_rect(fill = "#f7fafc", color = NA),
    panel.grid.major = element_line(color = "#e2e8f0", linewidth = 0.3),
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold", size = 18, color = "#2d3748", margin = margin(b = 5)),
    plot.subtitle = element_text(size = 11, color = "#718096", margin = margin(b = 15), face = "italic"),
    plot.caption = element_text(size = 9, color = "#718096", face = "italic"),
    axis.text = element_text(color = "#4a5568", size = 10),
    axis.title.y = element_text(color = "#718096", size = 10, face = "italic"),
    legend.position = "top",
    legend.text = element_text(color = "#4a5568", size = 10),
    plot.margin = margin(20, 20, 20, 20)
  )