有没有其他的方法来实现情节R的累积动画?

1dkrff03  于 2023-01-06  发布在  其他
关注(0)|答案(2)|浏览(108)
accumulate_by <- function(dat, var) {
  var <- lazyeval::f_eval(var, dat)
  lvls <- plotly:::getLevels(var)
  dats <- lapply(seq_along(lvls), function(x) {
    cbind(dat[var %in% lvls[seq(1, x)], ], frame = lvls[[x]])
  })
  dplyr::bind_rows(dats)
}

d <- txhousing %>%
  filter(year > 2005, city %in% c("Abilene", "Bay Area")) %>%
  accumulate_by(~date)

如果以上述函数的方式实现累积动画,则行数将增加过多。
我用的是一千帧,一万行,因为数据量大,已经打乱了正在进行的工作。
https://plot.ly/r/cumulative-animations/
除了这个例子,还有什么方法可以创建一个累积动画吗?帮帮我!

fv2wmkja

fv2wmkja1#

我现在面临着同样的问题,here描述的方法不适用于几千行数据。

我没有一个完全有效的解决方案,但我的想法是根据滑块值调整x轴范围,而不是重复使用每帧的数据(参见示例图p_range_slider)。不幸的是,这没有为我们提供“播放”按钮。

我认为可以以类似的方式使用animation_slider(),但是传递给animation_slider()steps参数没有求值(参见示例图p_animation_slider)。步骤仍然与动画帧绑定(如?animation_slider中所述)。
更新:此行为是 * 设计预期 * 参见sources

# don't let the user override steps
  slider$steps <- steps

此外,构建两个共享x轴的subplot也不成功。

library(plotly)

DF <- data.frame(
  n = 1:50,
  x = seq(0, 12, length = 50),
  y = runif(n = 50, min = 0, max = 10)
)

steps <- list()

for (i in seq_len(nrow(DF))) {
  steps[[i]] <- list(
    args = list("xaxis", list(range = c(0, i))),
    label = i,
    method = "relayout",
    value = i
  )
}

# Custom range slider -----------------------------------------------------

p_range_slider <- plot_ly(
  DF,
  x = ~ x,
  y = ~ y,
  type = "scatter",
  mode = "markers"
) %>% layout(title = "Custom range slider",
       xaxis = list(range = steps[[1]]$args[[2]]$range),
       sliders = list(
         list(
           active = 0, 
           currentvalue = list(prefix = "X-max: "), 
           pad = list(t = 20), 
           steps = steps)))

p_range_slider

# Animation slider --------------------------------------------------------

p_animation_slider <- plot_ly(
  DF,
  x = ~ x,
  y = ~ y,
  type = "scatter",
  mode = "markers",
  frame = ~ n
) %>% layout(title = "Animation slider") %>% animation_slider(
  active = 6,
  currentvalue = list(prefix = "X-max: "),
  pad = list(t = 20),
  steps = steps # custom steps are ignored
)

p_animation_slider

# subplot(p_range_slider, p_animation_slider, nrows = 2, margin = 0.05, shareX = TRUE)

看起来animation_slider()需要允许它的steps参数来执行自定义操作(从定义的框架中解除绑定)。
也许可以在R?-Filter in R中使用过滤器(避免轴重缩放)为python API重现this方法
下面是一个关于如何在R中使用过滤器变换和自定义范围滑块的示例,但是仍然没有动画(没有预先计算每帧):

DF <- data.frame(x = rep(1:10, 2), y = runif(20), group = rep(LETTERS[1:2], each = 10))

steps <- list()

for (i in seq_along(unique(DF$x))) {
  steps[[i]] <- list(
    args = list('transforms[0].value', i),
    label = i,
    method = "restyle",
    value = i
  )
}

p_filter_slider <- plot_ly(
  DF,
  x = ~ x,
  y = ~ y,
  color = ~ group,
  type = "scatter",
  mode = "lines+markers",
  transforms = list(
    list(
      type = 'filter',
      target = 'x',
      operation = '<=',
      value = ~ x
    )
  )
) %>% layout(title = "Custom filter slider",
             xaxis = list(range = c(0.5, length(unique(DF$x))+0.5)),
             sliders = list(
               list(
                 active = 0, 
                 currentvalue = list(prefix = "X-max: "), 
                 pad = list(t = 20), 
                 steps = steps))
             )

p_filter_slider

其他信息:

动画_滑块documentation
JS滑块attributes
相关的GitHub issue
RStudio社区question
这是plotly论坛上的相同的question

lf5gs5x2

lf5gs5x22#

我们遇到了类似的问题,每分钟有数千个数据点,所以作为第一步,我创建了另一个列“time_chunk”,它将时间四舍五入到分钟。
然后我用time_chunks来代替非常精确的分钟数据(带小数位),这样我得到了更合理的块数。
动画不是完全平滑的,但我们的数据大约是20-40分钟长,所以它是合理的,处理速度快。
所以,理论上说:

fig <- fig %>%
mutate(time_chunk = floor(time_min))

fig <- accumulate_by(fig, ~ time_chunk)

相关问题