英文:
Animating 2D random walk trajectory with ggplot in R
问题
I'm trying to create an animation that shows the trajectory of a random walk on the (x, y) plane over time. Each 'step' is a move in either the vertical or horizontal direction, never both. For example, if you start at (0, 0) you have only four options: (0, 1), (0, -1), (1, 0), (-1, 0); you can never go from (0, 0) to (1, 1) in one step.
我正在尝试创建一个动画,显示随机行走在(x, y)平面上随时间的轨迹。每个'步骤'都是垂直或水平方向的移动,而不是两者兼而有之。例如,如果你从(0, 0)出发,只有四个选择:(0, 1),(0, -1),(1, 0),(-1, 0);你不能在一步中从(0, 0)到(1, 1)。
I've written the random walk generating function to ensure that steps can only be taken across one axis at a time. Here is a regular ggplot without animation of one of these random walks using geom_path() and geom_point():
我编写了随机行走生成函数,以确保每次只能沿一个轴采取步骤。这里是一个普通的ggplot,没有动画,显示了其中一个随机行走,使用了geom_path()和geom_point():

When I try to animate the walk, however, it shows diagonal lines connecting the points which is impossible.
然而,当我尝试对行走进行动画处理时,它显示连接点的对角线,这是不可能的。

I can't figure out why this is happening. I've tried using geom_line() instead but that doesn't seem to fix the issue. The code for the animation is below:
我无法弄清楚为什么会发生这种情况。我尝试使用geom_line()代替,但似乎并没有解决问题。动画的代码如下:
ggplot(df, aes(x = x, y = y)) +
geom_path() +
geom_point() +
transition_reveal(along = ite) + # ite: numerical ordered variable in df representing the time from 0:n
scale_x_continuous(breaks = seq(min(df$x), max(df$x), by = 1)) +
scale_y_continuous(breaks = seq(min(df$y), max(df$y), by = 1)) +
coord_fixed() +
theme(panel.grid.minor = element_blank())
ggplot(df, aes(x = x, y = y)) +
geom_line() + # Try using geom_line() instead of geom_path()
geom_point() +
transition_reveal(along = ite) + # ite: numerical ordered variable in df representing the time from 0:n
scale_x_continuous(breaks = seq(min(df$x), max(df$x), by = 1)) +
scale_y_continuous(breaks = seq(min(df$y), max(df$y), by = 1)) +
coord_fixed() +
theme(panel.grid.minor = element_blank())
You can try replacing geom_path() with geom_line() in your animation code to see if it resolves the issue of diagonal lines between points.
英文:
I'm trying to create an animation that shows the trajectory of a random walk on the (x,y) plane over time. Each 'step' is a move in either the vertical or horizontal direction, never both. For example, if you start at (0,0) you have only four options: (0,1), (0,-1), (1,0), (-1,0); you can never go from (0,0) to (1,1) in one step.
I've written the random walk generating function to ensure that steps can only be taken across one axis at a time. Here is a regular ggplot without animation of one of these random walks using geom_path() and geom_point():

When I try to animate the walk, however, it shows diagonal lines connecting the points which is impossible.

I can't figure out why this is happening. I've tried using geom_line() instead but that doesn't seem to fix the issue. The code for the animation is below:
ggplot(df,aes(x=x,y=y)) +
geom_path() +
geom_point() +
transition_reveal(along=ite) + # ite: numerical ordered variable in df representing the time from 0:n
scale_x_continuous(breaks = seq(min(df$x), max(df$x), by = 1)) +
scale_y_continuous(breaks = seq(min(df$y), max(df$y), by = 1)) +
coord_fixed() +
theme(panel.grid.minor = element_blank())
答案1
得分: 0
你的动画帧数比你在ite上显示的状态数要小。这意味着至少偶尔,transition_reveal()必须“跳过”ite的几个状态,这导致有时绘制一条对角线。
增加动画的帧数以匹配ite的步数。你可以在显示动画时在animate()中指定,或者在保存时在anim_save()中指定。
英文:
The number of frames in your animation are smaller than the number of states you are revealing along ite. This means that at least every once in a while, transition_reveal() must "skip" across a few states of ite and this results in sometimes drawing a diagonal line.
Increase the frames in your animation to match the number of steps for ite. You can specify that in animate() when showing your animation or anim_save() when saving.
Example and Solution
Here's a demonstration using my own random walk function that works as you describe.
Note that it's useful to use {frame_along} within one of the labels in the plot that can be used to follow the particular state which is being shown.
library(ggplot2)
library(gganimate)
walk <- function(steps) {
x <- vector(length=steps)
y <- vector(length=steps)
x[1] <- 0
y[1] <- 0
direction <- 0
amt <- 0
for (i in 2:steps) {
direction <- rbinom(1, 1, 0.5)
amt <- sample(c(-1,1), 1)
if(direction==0) {
x[i] <- x[i-1] + amt
y[i] <- y[i-1]
}
else{
x[i] <- x[i-1]
y[i] <- y[i-1] + amt
}
}
return(data.frame(x,y, ite=1:steps))
}
df <- walk(200)
p <-
ggplot(df, aes(x,y)) +
geom_path() + geom_point() +
labs(title="it: {frame_along}") + # meant to write ite, but ok
theme_bw()
a <- p + transition_reveal(along=ite)
Here's the plot without animation.
Here's the animation. Note how the value for ite ("it: ##") is sometimes "jumping" across a few values.
To fix, you can specify nframes= within animate() instead of just calling a directly. You will note in the output that the value for ite is incrementing every state now and not skipping. This is why you always have the straight lines.
animate(a, nframes=200)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。





评论