1

I am trying to plot a map using gganimate, however, I keep getting Error: arguments have different crs.

This is my code:

library(tidyverse)
library(sf)
library(rnaturalearth)
library(countrycode)
library(gganimate)
library(transformr)

world <- ne_countries(scale = "medium", returnclass = "sf")
eurovision <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2022/2022-05-17/eurovision.csv')

to_plot <- 
  eurovision |> 
  select(year, artist_country, section, winner) |> 
  mutate(winnings = case_when(
    str_detect(section, "^grand-final$|^final$") & winner == TRUE ~ 1,
    TRUE ~ 0)) |>
  rename(admin = artist_country) |> 
  left_join(world) |> 
  select(year, admin, winnings, geometry) |>
  arrange(year) |> 
  group_by(admin) |> 
  mutate(winnings = lag(cumsum(winnings), default = 0)) |> 
  ungroup()

to_plot |> 
  ggplot() + 
  geom_sf(aes(fill = winnings, geometry = geometry)) +
  coord_sf(xlim = c(-25, 50), ylim = c(30, 80), expand = FALSE) +
  scale_fill_viridis_c(option = 1) + 
  labs(title = "{frame_time}") + 
  transition_time(year)

I tried to transform the geometry to latitute and longitude but it did not work. Can anyone help me?

Honorato
  • 111
  • 6
  • This appears to be a recent bug, my own code that worked fine a few weeks ago gets a similar error. https://stackoverflow.com/questions/75900914/problem-animating-with-geom-sf-and-gganimate-error-arguments-have-different-cr https://github.com/thomasp85/gganimate/issues/479 – ttalVlatt Apr 10 '23 at 19:52
  • That's what I imagined. Thank you for your feedback – Honorato Apr 10 '23 at 21:52

1 Answers1

0

Alternative to using gganimate package, I would try to generate individual still images and combine those images into video or gif file.

R code to generate still images

get_map <- function(y) {
  to_plot |> filter(year == y) %>% 
      ggplot() + 
      geom_sf(aes(fill = winnings, geometry = geometry)) +
      coord_sf(xlim = c(-25, 50), ylim = c(30, 80), expand = FALSE) +
      scale_fill_viridis_c(option = 1, 
                           limits = c(0, 7)
                           ) + 
      labs(title = y) 
    }

y_list <- to_plot$year %>% sort %>% unique
my_maps <- paste0("~/temp/m_", seq_along(y_list), ".png")
for (i in seq_along(y_list)){
    get_map(y = y_list[i])
    ggsave(my_maps[i], width = 4, height = 4)
}

It is likely there are some R packages to combine images into a video, but I am comfortable with python moviepy:

from moviepy.editor import *
plist = [f"~/temp/m_{x}.png" for x in list(range(1, 68))]
anim = ImageSequenceClip(plist, fps = 20)
anim.write_gif("gif_map.gif") # or anim.write_videofile("vid_map.mp4")

Although this approach needs a little bit more code, but it can be much more flexible than using an existing animation package. Due to size limit, the follow gif only included the last 29 images. enter image description here

Zhiqiang Wang
  • 6,206
  • 2
  • 13
  • 27