英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论