Skip to content

Instantly share code, notes, and snippets.

@padpadpadpad
Last active July 16, 2022 21:36
Show Gist options
  • Save padpadpadpad/b431a160da6a5f8356e1b4528d973b2f to your computer and use it in GitHub Desktop.
Save padpadpadpad/b431a160da6a5f8356e1b4528d973b2f to your computer and use it in GitHub Desktop.
# try and recreate famous Ed Hawkins climate change spiral graphic in R and ggplot2
# load packages
library(tidyverse)
library(MetBrewer)
library(gganimate)
# load in dataset from NASA
d <- read.csv('https://data.giss.nasa.gov/gistemp/tabledata_v4/GLB.Ts+dSST.csv', skip = 1)
head(d)
# make all columns numeric - there are some *** that i dont know what they mean
d <- mutate(d, across(everything(), as.numeric))
# replace NAs with 0 - just make them to have no positive or negative anomaly
d <- mutate(d, across(everything(), replace_na, 0))
# tidy the dataframe
d <- janitor::clean_names(d) %>%
pivot_longer(cols = jan:dec, names_to = 'month', values_to = 'anomaly')
# add a time column
d <- mutate(d, time = paste(year, toupper(month), sep = '-'),
time = lubridate::ym(time),
month2 = lubridate::month(time))
# create first plot
p1 <- ggplot(d, aes(month2, anomaly, col = anomaly)) +
geom_line(aes(group = year)) +
scale_color_gradientn('Temperature anomaly', colors = met.brewer(name='Homer1', direction=-1, override.order = F)) +
MicrobioUoE::theme_black() +
theme(panel.grid.major = element_blank(),
axis.title.x = element_blank()) +
scale_x_continuous(breaks = 1:12, labels = c('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
p1 + coord_polar()
# want to convert polar coordinates to cartesian to allow animation to go from December back to January
# using this link https://stackoverflow.com/questions/55132352/geom-path-refuses-to-cross-over-the-0-360-line-in-coord-polar
angles <- tibble(month = unique(d$month),
angle = seq(15, by = 30, length.out = 12))
d <- left_join(d, angles)
head(d)
# remove 2022 because its mid year
d <- filter(d, year < 2022)
# add buffer to make everything positive
buffer <- 3
d <- mutate(d, x_anomaly = sin(pi * angle/180) * (anomaly + buffer),
y_anomaly = cos(pi * angle/180) * (anomaly + buffer))
# create limits
limits <- c(-(max(d$anomaly) + buffer), max(d$anomaly) + buffer)
# create circles for some temperatures
circles <- data.frame(
r = c(buffer, buffer + 1, buffer - 1)) %>%
mutate(r = round(r, 0),
x0 = 0,
y0 = 0,
label = c('0ºC', '+1ºC', '-1ºC'))
# add months
months <- mutate(angles, anomaly = limits[2] + limits[2] * .1,
x_anomaly = sin(pi * angle/180) * anomaly,
y_anomaly = cos(pi * angle/180) * anomaly)
# increase limits slightly
limits <- limits + limits*.1
# create base plot
p1 <- ggplot(d, aes(x_anomaly, y_anomaly)) +
scale_x_continuous(limits = limits) +
scale_y_continuous(limits = limits) +
ggforce::theme_no_axes() +
theme(panel.background = element_rect(fill = 'black'),
legend.position = 'none') +
ggforce::geom_circle(aes(x0 = x0, y0 = y0, r = r), fill = NA, data = circles, inherit.aes = FALSE,col = 'white', size = 1.2) +
geom_text(aes(x_anomaly, y_anomaly, label = month), data = months, col = 'white', size = MicrobioUoE::pts(14)) +
geom_path(aes(col = anomaly), alpha = 0.9) +
geom_label(aes(x0, r, label = label), circles, fill = 'white', size = MicrobioUoE::pts(14)) +
coord_equal() +
transition_reveal(time) +
scale_color_gradientn('Temperature anomaly', colors = met.brewer(name='Homer1', direction=-1, override.order = F)) +
geom_text(aes(x = 0, y = 0, label = year, col = anomaly), size = MicrobioUoE::pts(24))
# save out the animation
gganimate::animate(p2, fps = 10, nframes = 120, duration = 60, width = 4, height = 4.5, units = 'in', renderer = av_renderer(), res = 150)
anim_save('~/climate_spiral.mp4', animation = last_animation())
gganimate::animate(p1, fps = 10, nframes = 120, duration = 60, width = 4, height = 4.5, units = 'in', res = 150)
anim_save('~/climate_spiral.gif', animation = last_animation())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment