Dynamic rectangle

43 Views Asked by At

I would like to animate with ggplot a time series and a rectangle.

My actual code is the following one:

library(ggplot2)
library(gganimate)

df <- data.frame(
    x = c(1,2,3,4,5,6,7,8,9,10),
    y = c(4,5,6,7,6,5,4,5,6,7)
)

p <- ggplot()+
    geom_line(data=df,aes(x=x,y=y))+
    geom_rect(aes(xmin=5,xmax=7,ymin=-Inf,ymax=+Inf),alpha=0.1)+
    transition_reveal(x)+
    theme_minimal()

animate(p,fps=20,renderer=gifski_renderer(file="test")) 

And I have this result:

actual animation

However, I want the rectangle to appear when the time series reach it. And I want the rectangle to increase with the time series. I don't want the rectangle to appear instantly.

Can this problem be solved with gganimate?

1

There are 1 best solutions below

0
stefan On

Not 100% sure about your desired result but here is one possible approach using a filtered dataset and multiple rectangles:

library(ggplot2)
library(gganimate)

p <- ggplot(data = df, aes(x = x, y = y)) +
  geom_line() +
  geom_rect(
    data = ~ subset(., x >= 5),
    aes(xmin = x, xmax = x + 1, ymin = -Inf, ymax = +Inf, group = x),
    alpha = 0.1
  ) +
  transition_reveal(x) +
  theme_minimal()
p
#> `geom_line()`: Each group consists of only one observation.
#> ℹ Do you need to adjust the group aesthetic?
#> `geom_line()`: Each group consists of only one observation.
#> ℹ Do you need to adjust the group aesthetic?

#animate(p, fps = 20, renderer = gifski_renderer(file = "test"))

Or for a smoother transition you could use a separate data frame for the rectangles like so:

width <- .05

df_rect <- data.frame(
  x = seq(5, 10, width),
  y = NA_real_
)

p <- ggplot(data = df, aes(x = x, y = y)) +
  geom_line() +
  geom_rect(
    data = df_rect,
    aes(xmin = x, xmax = x + width, ymin = -Inf, ymax = +Inf, group = x),
    alpha = 0.1
  ) +
  transition_reveal(x) +
  theme_minimal()
p
#> `geom_line()`: Each group consists of only one observation.
#> ℹ Do you need to adjust the group aesthetic?
#> `geom_line()`: Each group consists of only one observation.
#> ℹ Do you need to adjust the group aesthetic?