Display Different Time Elements at Different Speeds in Gganimate

Display different time elements at different speeds in gganimate

This is my rudimentary try by making a helper column which can be used as our transition_time to show how we can have different time step but desired labels.

You can later spend some more time to make a better *timestep columns which is more sophisticated and precisely meets your needs.

The main idea/point here is that we can use functions on the frame_time to get the labels as needed while the transition_time can be manipulated.

library(ggplot2)
library(gganimate)
library(dplyr)

g <- airquality %>%
group_by(Month) %>%
mutate(timestep = if_else(Month==5, ((1:n())-1)/2 + Month, 15 + Month)) %>%
ggplot(aes(Day, Temp, group = interaction(Month, Day))) +
geom_point(color = 'red', size = 1) +
transition_time(timestep) +
shadow_mark(colour = 'black', size = 0.75) +
enter_fade() +
labs(title = 'Month: {if_else(frame_time<21,5, ceiling(frame_time-15))}')

animate(g, nframes = 100)

Sample Image

Created on 2019-06-02 by the reprex package (v0.3.0)

How to make dots in gganimate appear and not transition

The transitions are ultimately tied to each data point's group. In your code, all the Day 1 data points are sharing a group, and so they appear from the old ones.

Give the points their own group (e.g. by using group = interaction(Month, Day)) and it should work.

a <- ggplot(airquality, aes(Day, Temp, 
group = interaction(Month, Day))) +
geom_point(color = 'red', size = 1) +
transition_time(Month) +
shadow_mark(colour = 'black', size = 0.75) +
enter_fade() # I liked the look of this, but fine to leave out
animate(a, nframes = 100)

Sample Image

gganimate::transition_time results in flying polygons

This is a grouping issue. You need to be explicit with your groups. In this case, create an interaction of Year and w_l

You can use the package rnaturalearth to get world / country maps more conveniently.

library(tidyverse) 
library(gganimate)

world <- rnaturalearth::ne_countries( returnclass = 'sf') %>% filter(admin!= 'Antarctica')

url <- "https://www.blog.cultureofinsight.com/data/wc.xlsx"
httr::GET(url, httr::write_disk("wc.xlsx", overwrite=TRUE))

winners <- readxl::read_excel("wc.xlsx") %>%
gather(w_l, country, winner:runner_up) %>%
mutate(w_l = factor(w_l, levels = c("winner", "runner_up")))

wc_geo <- left_join(world, winners, by = c("admin" = "country")) %>%
drop_na(Year)

p <-
ggplot() +
geom_sf(data = world, colour = "#ffffff20", fill = "#2d2d2d60", size = .5) +
geom_sf(data = wc_geo, aes(fill = w_l, group = interaction(w_l, Year))) +
scale_fill_manual(values = c("#D9A441", "#A8A8A8"), name = NULL, labels = c("Winner", "Runner-Up")) +
theme(legend.position = c(0.9, 1.01), legend.direction = "horizontal", axis.text = element_blank(),
panel.grid.minor = element_blank(), panel.grid.major = element_blank())

anim <- p + transition_time(Year)

animate(anim)

Sample Image

Created on 2020-04-24 by the reprex package (v0.3.0)

P.S. It's always the same countries, isn't it...

latest gganimate: How to have a fixed plot in the background?

This has already been addressed in an issue for gganimate on GitHub: https://github.com/thomasp85/gganimate/issues/94

Basically you specify the the layers that are meant to be static with a separate data frame from the one you initially passed to ggplot. The example in the GitHub ticket I referred to is

library(gganimate)
#> Loading required package: ggplot2
ggplot(dat = data.frame(x=1:10,y=1:10), aes(x=x,y=y)) +
geom_point() +
geom_line(data = data.frame(x2 = 1:10, y = 1:10),
aes(x = x2, y = y, group = 1)) +
transition_time(x)
animate(last_plot(), nframes = 50)

Here the line is held static, while the point is moving.

How to use multiple cores to make gganimate faster

This is a pull request, meaning that the code is available on GitHub as a branch, but hasn't yet been merged in gganimate master.

You could clone it or copy the modified package directory on your system.

Then :

  • make sure that devtools package is installed
  • open gganimate.Rproj
  • run devtools::load_all(".")

The parallel version is ready to run :

anim <- ggplot(mtcars, aes(mpg, disp)) +
transition_states(gear, transition_length = 2, state_length = 1) +
enter_fade() +
exit_fade()

future::plan("sequential") ## default
t0 <- system.time(animate(anim))
print(t0)

# user system total
# 4.384615 1.360656 1.893855

future::plan("multiprocess", workers = 4L)
t1 <- system.time(animate(anim))
# user system total
# 1.30 0.61 3.58

print(t0 / t1)
# user system total
# 4.384615 1.360656 1.893855

To avoid load_all you could open the DESCRIPTION file and rename the package :

Package: gganimateparallel
Type: Package
Title: A Grammar of Animated Graphics
...

As vignettes seem to have difficulties to build, you can just remove the vignettes directory.

Then RStudio / Build / Install and restart or from the package's directory

Rcmd.exe INSTALL --no-multiarch --with-keep.source .

gganimateparallel is now available on your system as a library.

Credits @HenrikBengtsson for the incredible job done on future!



Related Topics



Leave a reply



Submit