我正在制作一个动画,其 x 轴上的因子级别与动画中的
frame
相同。我想将完整数据集显示为固定数据集,并在动画中让单个轨迹跟随时间序列。下面是一个玩具示例,显示了我所看到的问题。任何帮助将不胜感激!
library(dplyr)
library(plotly)
#### create data
dat <- expand.grid(x = 1:5, f = 1:5)
dat <- dat %>% mutate(y = x^f/10) %>%
arrange(desc(f)) %>%
mutate(fr = letters[f],
fr = factor(fr, levels = unique(fr))) %>%
data.frame()
三个图 - 其中两个分别显示 2 条迹线中的每一个(正确绘制),第三个图显示组合的迹线,其中动画滑块错误地反转顺序。
### stationary plot of all data - showing correct ordering of x-axis values
plot_ly(dat) %>%
add_trace(x = ~fr,
y = ~y,
type = "scatter",
mode = "markers")
#### animated trace, showing correct ordering of the animation slider(from e to a)
plot_ly(dat) %>%
add_trace(x = ~fr,
y = ~y,
frame = ~fr,
type = "scatter",
mode = "markers") %>%
animation_opts(frame = 500)
#### both traces combined, showing the problem - the x-axis is ordered correctly,
#### but the animation slider reversed order, now playing from a to e. e to a)
plot_ly(dat) %>%
add_trace(x = ~fr,
y = ~y,
type = "scatter",
mode = "markers") %>%
add_trace(x = ~fr,
y = ~y,
frame = ~fr,
type = "scatter",
mode = "markers") %>%
animation_opts(frame = 500) %>%
animation_slider()
我无法找到可以解决此问题的参数,也无法对所调用的函数进行一些重新排列。这很烦人吧?
这里有一个解决方法——虽然它有效,但对于一般使用来说不太好。
我提供了功能
fixer()
。在该函数中,有一行以 plt$x$data[[2]]
开头的代码。 2
由您调用痕迹的顺序决定。由于 frames
迹线被称为“第二”,因此这是一个“二”。
除此之外,代码中的注释用于解释如何以及为什么。如果有任何不清楚或未按您的预期工作,请告诉我。
fixer <- function(plt) {
plt <- plotly_build(plt) # build to get data
# capture current animation order in plot
curOrd <- invisible(lapply(1:length(plt$x$frames), function(j) {
frs[[j]]$name
})) %>% unlist()
fixOrd <- match(curOrd, levels(dat$fr)) # compare current order; get index to fix
plt$x$frames <- plt$x$frames[fixOrd] # rearrange frames & slider (steps)
plt$x$layout$sliders[[1]]$steps <- plt$x$layout$sliders[[1]]$steps[fixOrd]
# change the base anim frame (when not animating)
plt$x$data[[2]] <- plt$x$frames[fixOrd][[1]]$data[[1]]
plt # return plot
}
plot_ly(dat) %>%
add_trace(x = ~fr,
y = ~y,
type = "scatter",
mode = "markers") %>%
add_trace(x = ~fr,
y = ~y,
frame = ~fr,
type = "scatter",
mode = "markers") %>%
animation_opts(frame = 500) %>%
animation_slider() %>% fixer() ## <<-- I'm new!