Home > Mobile >  How to animate geom_path plots with gganimate in R
How to animate geom_path plots with gganimate in R

Time:12-02

I am trying to make a smooth animation of lines that move over time. Here is some example data:

test.data <- data.frame( depth  = rep( seq( 1, 10 ), 10 ), 
                         time = rep( 1:10, times = 1, each = 10 ),
                         temp = rep( x, 10 )   rep( 0:9, each = length( x ) ) )

Now arrange the data so that geom_path links the data correctly

 arrange( test.data, depth, time )  ## arrange by depth for plotting

Now make the static plot with all the data shown:

ggplot( test.data, aes( x = temp, y = depth, group = time ) )  
        ylim( 10, 0 )  
        labs( y = "Depth (km)", 
              x = "Temp (C)",
              color = "Time")  
        geom_path( aes( color = time ) )

Here is the static plot: enter image description here

Now do the animation using gganimate

library(gganimate)

plot.for.gif <- test.data %>% 
   ggplot( aes( x = temp, y = depth, group = time ) )  
   ylim( 10, 0 )  
   labs( y = "Depth (km)", 
         x = "Temp (C)",
         color = "Time (Ma)")  
   geom_path( aes( color = time ) )

plot.animation = plot.for.gif  
   transition_time( time = time )  
   labs( subtitle = "Time (Ma): {frame_time}" )  
   shadow_mark( past = TRUE, future = FALSE, exclude_layer = NULL )

   animate( plot.animation, height = 1400, width = 800, fps = 10, duration = 15, res = 150 )

This is the resulting plot:

enter image description here

The problem is that the lines do not blend into one another, they jump from one frame to another. I'd like to get them to move smoothly between discrete frames.

I've tried playing with shadow_wake() and enter_fade() but neither work. It seems like gganimate() doesn't smooth lines connecting datapoints well, but I am perhaps missing an easy fix.

Any help would be appreciated!

CodePudding user response:

You didn't provide x in your question, but presuming it's something like this:

x <- seq(0, 9)^(2/3) * 15

Then we can do:

test.data <- data.frame( depth  = rep( seq( 1, 10 ), 10 ), 
                         time = rep( 1:10, times = 1, each = 10 ),
                         temp = rep(x, 10 )   rep( 0:9, each = length( x ) ) )

library(gganimate)

plot.for.gif <- test.data %>% 
  mutate(time = factor(time)) %>%
  ggplot( aes(x = temp, y = depth, color = as.numeric(time)) )  
  geom_path()  
  labs(color = "time")  
  scale_y_reverse()  
  transition_states(time, transition_length = 1, state_length = 0.1) 

animate(plot.animation, fps = 30, duration = 3, detail = 3)

enter image description here

CodePudding user response:

You have to leave shadow_mark(past = TRUE,...) out. This keeps the lines from the past in the animation.

I have created an own DF which comes close to yours. (I couldn't figure out, how your variable temp was created.)

If you then leave group = time out you get a smooth animation.

library(gganimate)
library(dplyr)

depth  = rep( seq( 1, 10 ), 10 )
time = rep( 1:10, times = 1, each = 10 )
temp = depth   time

test.data <- data.frame(depth, time)
arrange( test.data, depth, time ) 

anim <- ggplot( test.data, aes( x = temp, y = depth))  
  ylim( 10, 0 )  
  labs( y = "Depth (km)", 
        x = "Temp (C)",
        color = "Time")  
  geom_path( aes( color = time ) )  
  transition_time(time) 
  #shadow_mark(past = T) # leave this out

animate(anim)

enter image description here

  • Related