I am new to the gganimate
package, and I encountered a problem in using shadow_mark
. I have three layers of animation objects, and I only want to keep the trail in one of them. However, exclude_layer
doesn't seem to work on, specifically, geom_line
.
Here is the problematic code block:
try_anim = ggplot(data = df) +
scale_y_continuous(limits = c(0,1)) +
stat_function(data=df["mu_s1"], fun = f, linetype = "dashed", color="black") +
stat_function(data=df["mu_s1"], fun = g, color="black", na.rm = TRUE) +
geom_point(data = df3, aes(x=a, y=g_a, group = t), size = 1.5) +
geom_line(data = df3, aes(x=a, y=g_a, group = t), size = 1.5) + # problematic line
geom_point(aes(x=mu_s1, y=z), color = "red", size = 2.5) + # only want shadow_mark on this line
transition_time(t) +
shadow_mark(color="red", size = 1, exclude_layer = 1:2)
animate(try_anim, fps = 10, duration = 10, renderer = gifski_renderer("~/tryanim.gif"))
If the issue needs to be diagnosed with an MWE, here is one:
rm(list=ls())
library(ggplot2)
library(gganimate)
library(gifski)
# model premises
mu = 1/2
p = 2/3
q = 0.8
r00 = 1
r01 = 0
r11 = 1
r10 = 0
mu_p_bar =(r00-r10)/((r00-r10)+(r11-r01))
v00 = 1.25
v01 = 0.25
v11 = 0.75
v10 = -0.25
mu_a_bar =(v00-v10)/((v00-v10)+(v11-v01))
# define functions
f <- function(x){
ifelse(x <= mu_p_bar, (r01-r00)*x+r00, ifelse(x > mu_p_bar, (r11-r10)*x+r10, NA))
}
g <- function(x){
ifelse(x==mu_a_bar,
NA,
(x < mu_a_bar)*((r01-r00)*x+r00) + (x >mu_a_bar)*((r11-r10)*x+r10))
}
# create datasets used in the code
nsample = 100
mu_s1 = seq(0, 1, length.out = nsample)
mu_s10 <- ((1-q)*mu_s1)/((1-q)*mu_s1+q*(1-mu_s1))
mu_s11 <- ((q)*mu_s1)/((q)*mu_s1+(1-q)*(1-mu_s1))
g_mu_s10 = g(x=mu_s10)
g_mu_s11 = g(x=mu_s11)
s <- (g(x=mu_s11) - g(x=mu_s10)) / (mu_s11 - mu_s10)
z <- s*(mu_s1-mu_s10)+g(x=mu_s10)
df <- data.frame(mu_s1, mu_s10, mu_s11, g_mu_s10, g_mu_s11, s,z)
df <- df[order(mu_s1),]
df["t"] = c(1:nsample)
df1 = df[c("mu_s10","g_mu_s10", "t")]
names(df1) <- c("a", "g_a", "t")
df1["side"] = 0
df2 = df[c("mu_s11","g_mu_s11", "t")]
names(df2) <- c("a", "g_a", "t")
df2["side"] = 1
df3 = rbind(df1, df2)
# the problematic code block
try_anim = ggplot(data = df) +
scale_y_continuous(limits = c(0,1)) +
stat_function(data=df["mu_s1"], fun = f, linetype = "dashed", color="black") +
stat_function(data=df["mu_s1"], fun = g, color="black", na.rm = TRUE) +
geom_point(data = df3, aes(x=a, y=g_a, group = t), size = 1.5) +
geom_line(data = df3, aes(x=a, y=g_a, group = t), size = 1.5) + # problematic line
geom_point(aes(x=mu_s1, y=z), color = "red", size = 2.5) + # only want shadow_mark on this line
transition_time(t) +
shadow_mark(color="red", size = 1, exclude_layer = 1:2)
animate(try_anim, fps = 10, duration = 10, renderer = gifski_renderer("~/tryanim.gif"))
This is the output, where you can see the unwanted shadow of the lines.
I appreciate any suggestions or help!
The issue is that using exclude_layer = 1:2
you are only excluding the stat_function
layers from your animation. Instead, if you only want to have a shadow mark on the last geom_point
you have to use exclude_layer = 3:4
(or 1:4
but as far as I get it, this makes no difference) to drop the first geom_point
and the geom_line
.
library(ggplot2)
library(gganimate)
library(gifski)
try_anim <- ggplot(data = df) +
scale_y_continuous(limits = c(0, 1)) +
stat_function(data = df["mu_s1"], fun = f, linetype = "dashed", color = "black") +
stat_function(data = df["mu_s1"], fun = g, color = "black", na.rm = TRUE) +
geom_point(data = df3, aes(x = a, y = g_a, group = t), size = 1.5) +
geom_line(data = df3, aes(x = a, y = g_a, group = t), size = 1.5) + # problematic line
geom_point(aes(x = mu_s1, y = z), color = "red", size = 2.5) + # only want shadow_mark on this line
transition_time(t) +
shadow_mark(color = "red", size = 1, exclude_layer = 3:4)
animate(try_anim, fps = 10, duration = 10, renderer = gifski_renderer("tryanim.gif"))