I want to animate some data as a black line that is circumscribed by two static red lines. The static lines are UP and DOWN. My animated data is in y and the timeline is x.
I tried a lot - with transition_components()
and transition_layers()
- but nothing worked... but perhaps I had some failures in my code I'm not sure... How to assign color to lines I found Changing line colors with ggplot() but my handling isn't proper...
My gganimate code that has to be completed:
# load the needed packages
library(gifski)
library(ggplot2)
library(gganimate)
theme_set(theme_bw())
# add the time vector x
### 10.1 seconds with timestep 0.1 seconds
x=rep(seq(from=0,to=10,by=0.1),times=3)
# y should be the line in the plot which should be animated
y=c(seq(from=0,to=10,length.out=which(round(x,1)==2)[1]),rep(10,times=which(round(x,1)==5)[1]-which(round(x,1)==2)[1]),10*0.95^(seq(from=1,by=1,length.out=50)))
# UP and DOWN should be static lines in the animated plot
### there shouldn't be a "linemoving" from left to rigth side of the plot
UP=c(seq(from=1,to=12,length.out=which(round(x,1)==1.8)[1]),
rep(12,times=which(round(x,1)==5.5)[1]-which(round(x,1)==1.8)[1]),
seq(from=12,to=4,length.out=length(seq(from=0,to=10,by=0.1))-which(round(x,1)==1.8)[1]-(which(round(x,1)==5.5)[1]-which(round(x,1)==1.8)[1]))
)
DOWN=c(seq(from=0,to=8,length.out=which(round(x,1)==2.2)[1]),
rep(8,times=which(round(x,1)==4.5)[1]-which(round(x,1)==2.2)[1]),
seq(from=8,to=1,length.out=length(seq(from=0,to=10,by=0.1))-which(round(x,1)==2.2)[1]-(which(round(x,1)==4.5)[1]-which(round(x,1)==2.2)[1]))
)
value=c(y,UP,DOWN)
h=length(seq(from=0,to=10,by=0.1))
variable=c(rep("y", h), rep("UP", h), rep("DOWN", h) )
# the dataframe with the three columns
df=data.frame(x, variable, value)
p=ggplot(df, aes(x=x, y=value, group=variable, colour=variable ) ) + geom_line(size=2) + scale_color_manual(values=c("black", "red", "red")) # I want that y is a black line and UP and DOWN are red lines
# x is my time variable in the dataframe
p2=p + transition_reveal(x)
# animating p2
animate(p2)
The finished plot should look like this picture
To me here are arising some questions:
Question 1 is the trickiest. You need to organize your data such that the x values for your two static lines have a different name (such as static_x
), and do not have any actual x
values. It's probably easiest to split df into two different frames to do this:
df_y <- df[variable == "y", ]
df_not_y <- df[variable != "y",]
df_not_y$static_x <- df_not_y$x
df_not_y <- df_not_y[names(df_not_y) != "x"]
Then, to handle question 4, we will remove all values of the variable UP
before 1 second:
df_not_y$value[df_not_y$static_x < 1 & df_not_y$variable == "UP"] <- NA
Now we can plot. We want two geom_line
calls, one for the static variables and one for the moving variable. To answer question 2, we assign the colours by name inside scale_color_manual
so that we ensure the levels are correct.
p <- ggplot(df_y, aes(x = x, y = value, colour = variable)) +
geom_line(aes(x = static_x), data = df_not_y, size = 2) +
geom_line(size = 2) +
scale_color_manual(values = c(UP = "red", y = "black", DOWN = "red"))
p2 <- p + transition_reveal(x)
animate(p2)
That leaves question 3. In this case, I simply right clicked on the viewer panel and selected "save image", but you can also do gganimate::anim_save("mygif.gif", last_animation())
if you find this more convenient.