Say that I have these data that I want to animate with ggplot2
+gganimate
.
library(ggplot2)
library(gganimate)
data <- data.frame(day = c(1:5, 1:5),
x = c(rep(2,5), rep(4, 5)),
y=c(rep(1, 5), rep(2, 5)))
data <- data[c(1:2, 4:10),]
The goals of the animation/question are to
No. 1. have flashing red dots for each day+x+y dot that is in the dataset (meaning there is an observation for that day+x+y). The flash should be very brief. After it flashes, it should go to the background color (controlled by shadow_mark) of black. Note that I do not want dots to float around, only stay where they are (see solution to this question: How to make dots in gganimate appear and not transition).
No. 2. I also want the dots to flash beginning exactly when their day begins. Here is code that does only part of what I want, but fails to (fully) address numbers 1 and 2:
ggplot(data, aes(x,y, group=interaction(x,y))) +
geom_point(color="red", size=3) +
transition_time(day) +
shadow_mark(color="black", size=3) +
theme(plot.subtitle = element_text(hjust = 0.7)) +
labs(subtitle = paste('day: {frame_time}')) -> a
anim_save("test.gif", a, end_pause=6, width = 400, height = 450, duration=15)
Here is the resulting animation:
This has two problems that I hope to get resolved:
data
is missing day 3 for the (x=2,y=1) dot) as expected. However it turns to black partway through day 3 and turns back to red partway through day 4, but I would like it to turn to black exactly at when day 3 begins and flash red exactly when day 4 begins. Note that I am not sure if this time misalignment is caused by transition_time
behavior or the subtitle frame_time
behavior or something else.Any suggestions?
Here's an approach where the data is prepped to give 25 frames to each day, where the color is made to flash for just the first of those:
library(dplyr); library(tidyr)
f_per_day <- 25
animate(
data %>%
uncount(f_per_day, .id = "frame") %>%
mutate(time = day + (frame-1)/f_per_day) %>%
ggplot(aes(x, y, color = frame == 1)) +
geom_point(size = 3) +
scale_color_manual(values = c("black", "red"), guide = F) +
theme(plot.subtitle = element_text(hjust = 0.7)) +
labs(subtitle = paste('day: {floor(frame_time*10)/10}')) +
transition_time(time),
width = 400,
height = 450,
fps = 25,
type = "cairo")