Plotly - alternative implementation of cumulative animations

I'm currently trying to create cumulative animations without accumulating the data for each frame with R-Plotly. The approach described on the plotly website is not applicable for a few thousand rows of data (see p_animation_example).

I already tried to revive existing questions / issues on GitHub, Plotly Forum and Stack Overflow, but received no replies so far.

My idea was to adapt the x-axis range based on the slider value instead of re-using the data for each frame (see example plot p_custom_slider). This unfortunately doesn't provide us with the "Play"-button.

I thought it might be possible to use animation_slider() in a similar way but the steps argument passed to animation_slider() is not evaluated (see example plot p_custom_animation). The steps remain tied to the animation frames (as stated in ?animation_slider) because the user is not allowed to change the steps:

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

(see the sources)

Also building a subplot of both sharing the x-axis wasn't successful.

Here is what I tried so far:

library(plotly)
library(htmlwidgets)
library(dplyr)
library(lazyeval)

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)
}

n <- 100

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

DFacc <- accumulate_by(DF, ~n)

cat("Initial row count: ", nrow(DF), "\nAccumulated row count: ", nrow(DFacc), "\n")


# Plotly example ----------------------------------------------------------

p_animation_example <- plot_ly(
  DFacc,
  x = ~x,
  y = ~y,
  type = "scatter",
  mode = "markers",
  frame = ~frame
)

p_animation_example # expected behaviour but resulting in big files
# saveWidget(p_animation_example, "animation_example.html") # ~20 MB file for n = 1000


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

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
  )
}

p_custom_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_custom_slider # no "Play" button available
# saveWidget(p_custom_slider, "custom_slider.html") # ~3 MB file for n = 1000


# Custom animation slider -------------------------------------------------

p_custom_animation <- 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_custom_animation # axis remains unchanged / custom steps are ignored
# saveWidget(p_custom_animation, "custom_animation.html") # ~3.5 MB file for n = 1000


# subplot -----------------------------------------------------------------
# subplot(p_custom_slider, p_custom_animation, nrows = 2, margin = 0.05, shareX = TRUE) # play button not working

Any other Ideas to approach this are highly appreciated.

Maybe it is possible to reproduce this approach for the python api using a filter transform (avoids axis-rescaling) in R? - Filter in R

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.