thomasp85 / gganimate

A Grammar of Animated Graphics
https://gganimate.com
Other
1.95k stars 310 forks source link

Animating a vector field along a given curve #452

Closed bkostadi closed 1 year ago

bkostadi commented 2 years ago

Happy 2022!

Thanks for creating gganimate! It looks amazingly useful for quickly creating animations, not just data science related, but to visualize any mathematical concepts. I wish there were a book or at least a comprehensive tutorial on using gganimate with easy enough to understand examples, not just related to data science, but more general mathematical and art visualizations.

I wanted to animate a vector field along a given curve, using gganimate, so that at any given moment the current frame shows only the vector at the current position along the curve, but the entire curve is shown in every frame.

I could not find easy enough to understand examples of using gganimate, so I tried something based on guessing what might work. In the code chunk below, I almost created what I want but the curve loops back. Also, the curve looks very pixelated. I am new to gganimate, so I am not sure what kind of issue is that. Any help would be much appreciated. Thanks!

library(gganimate)
library(ggplot2)
data<- tibble(x = seq(0,20,by = 0.1), y = sqrt(x) , vx = 1, vy = 1)
p<-ggplot(data, aes(x,y)) +
  coord_fixed() +
  geom_function(fun=function(u) sqrt(u), xlim=c(0,20), col="gray") +
  geom_line() +
  geom_point() +
  geom_segment(aes(x = x, y = y, xend = x + vx, yend = y + vy), 
               arrow = arrow(angle = 30, length = unit(2, "mm"),
               ends = "last", type = "open"), col="blue")
p + transition_reveal(x)

The code chunk above produced the output: test

thomasp85 commented 1 year ago

both the connection and the pixelation happens for the same reason. You are drawing a curve for each row in data, due to how ggplot2 works. As you are laying all those curves on top of each other the antialiasing compounds into pixelation.

This is also the reason for the connection. Transition reveal does that due to the multitude of curves (I'll not argue this makes sense in this case but changing it will impact 99% of all other use cases)

To "fix" your animation (as I understand it to look). You'd instead have a second static geom_line() rather than a geom_function() by using a dataset that doesn't contain the transition parameter (x)

library(gganimate)
library(ggplot2)
data<- tibble(x = seq(0,20,by = 0.1), y = sqrt(x) , vx = 1, vy = 1)
p<-ggplot(data, aes(x,y)) +
    coord_fixed() +
    geom_line(aes(x = seq(0,20,by = 0.1), y = sqrt(seq(0,20,by = 0.1))), data = tibble(), col="gray") +
    geom_line() +
    geom_point() +
    geom_segment(aes(x = x, y = y, xend = x + vx, yend = y + vy), 
                 arrow = arrow(angle = 30, length = unit(2, "mm"),
                               ends = "last", type = "open"), col="blue")
p + transition_reveal(x)
bkostadi commented 1 year ago

Thank you for taking the time, Thomas! I'd like to learn more about gganimate. It has a great potential for creating animated math inspired visualizations, not just data visualizations.