I've created maps of observations of several species over time and I want to place them side-by-side for comparison. I created the gifs using gganimate and wanted to use image_append() from magick to combine them. The problem arises when using image_read(): even though the gifs created by gganimate are 100 frames each and transition at the same frames, image_read() creates gifs with varying lengths. This means that when combined, the years aren't aligned. How can I standardize the output of image_read()?
This same question was asked in 2021 but was never answered. Hopefully including reprex will help potential answerers.
Sample code:
library(sf)
library(ggplot2)
library(gganimate)
library(transformr)
library(magick)
r <- data.frame(YEAR = c(1995:2022),
TOTAL = c(runif(28, 0, 15)),
LONG = c(runif(28, -80, -78)),
LAT = c(runif(28, 38, 40)))
t <- data.frame(YEAR = c(1995:2022),
TOTAL = c(runif(28, 0, 20)),
LONG = c(runif(28, -80, -78)),
LAT = c(runif(28, 38, 40)))
r.map <- st_as_sf(r, coords = c("LONG", "LAT"), crs = 4326)
t.map <- st_as_sf(t, coords = c("LONG", "LAT"), crs = 4326)
r.map2 <- ggplot() +
geom_sf(data = r.map, aes(size = TOTAL, alpha = ifelse(TOTAL == 0, 0, 1))) +
guides(alpha = "none") +
scale_alpha(range = c(0,1)) +
transition_states(YEAR, transition_length = 0, state_length = 1) +
ggtitle("{closest_state}") +
shadow_mark(alpha = ifelse(r.map$TOTAL == 0, 0, 0.25))
t.map2 <- ggplot() +
geom_sf(data = t.map, aes(size = TOTAL, alpha = ifelse(TOTAL == 0, 0, 1))) +
guides(alpha = "none") +
scale_alpha(range = c(0,1)) +
transition_states(YEAR, transition_length = 0, state_length = 1) +
ggtitle("{closest_state}") +
shadow_mark(alpha = ifelse(t.map$TOTAL == 0, 0, 0.25))
r_gif <- animate(r.map2)
t_gif <- animate(t.map2)
Check the length of the gifs created by gganimate (this is an inelegant solution, there may be another way to do this):
length(frame_vars(r_gif)$frame)
> 100
length(frame_vars(t_gif)$frame)
> 100
Read into magick and check the lengths again:
r_mgif <- image_read(r_gif)
t_mgif <- image_read(t_gif)
length(r_mgif)
> 75
length(t_mgif)
> 66
This is my first time posting here so please let me know if my post is missing anything! Thank you for your help.