我正在尝试制作动画图,在其中引入新的轨迹,对轨迹进行动画处理,然后重新缩放轴。我很难让这些东西一起工作。下面是一个代表。除了当我同时具有“ Animate Traces”和“ Rescale Axis”时,它都有效,然后在每次迭代时都会重置轴缩放。
Using Proxy Interface in Plotly/Shiny to dynamically change data
https://community.plot.ly/t/how-to-efficiently-restyle-update-modify-plot-containing-frames/5553
https://plot.ly/javascript/plotlyjs-function-reference/
https://plot.ly/javascript/animations/
很难遵循Plotly文档。我无法获得addFrames,relayout,重新设置样式,做出反应或更新以适合我的工作。我最幸运的是拥有动画。非常感谢您的帮助,我已经为此努力了两个星期。
# plotly_add_anim13.R
library(shiny)
library(plotly)
library(dplyr)
library(purrr)
ui <- fluidPage(
checkboxInput("add", "Add Trace", TRUE),
checkboxInput("animate", "Animate Traces", FALSE),
checkboxInput("rescale", "Rescale Axis", FALSE),
plotlyOutput("plot")
)
server <- function(input, output, session){
my <- reactiveValues(
fnumber = NA, # frame number
frame = NA, # frame data list
ntraces = NA, # number of traces
xrange = NA # xaxis range
)
speed = 1000 # redraw interval in milliseconds
output$plot <- renderPlotly({
isolate({
cat("renderPlotly\n")
my$fnumber <- 1
my$ntraces <- 2
f <- as.character(my$fnumber)
x <- runif(2)
y <- rep(runif(1), 2)
t <- c("A", "B")
ids0 <- paste0(my$ntraces-2, letters[1:2])
ids1 <- paste0(my$ntraces-1, letters[1:2])
my$xrange <- c(0,1)
# https://community.plot.ly/t/how-to-efficiently-restyle-update-modify-plot-containing-frames/5553
my$frame <- list(
name = f,
data = list(
list(x=x, y=y, frame=f, ids=ids0, type="scatter", mode="lines", showlegend=FALSE),
list(x=x, y=y, frame=f, ids=ids1, type="scatter", mode="text", text=t, showlegend=FALSE)
),
traces = as.list(as.integer(c(my$ntraces-2, my$ntraces-1))),
layout = list(xaxis=list(range=my$xrange, zeroline=FALSE),
yaxis=list(range=c(0,1), tickmode="array", tickvals=seq(0,1,0.2), ticktext=seq(0,1,0.2)))
)
p <- plot_ly()
p <- do.call(add_trace, prepend(my$frame$data[[1]], list(p)))
p <- do.call(add_trace, prepend(my$frame$data[[2]], list(p)))
p <- do.call(layout, prepend(my$frame$layout, list(p)))
p <- animation_opts(p, frame=speed, transition=speed)
p
})
})
proxy <- plotlyProxy("plot", session=session)
# https://shiny.rstudio.com/reference/shiny/0.14/reactiveTimer.html
autoInvalidate <- reactiveTimer(speed*2)
observeEvent(autoInvalidate(), {
# req(NULL)
# https://stackoverflow.com/questions/50620360/using-proxy-interface-in-plotly-shiny-to-dynamically-change-data
# https://community.plot.ly/t/how-to-efficiently-restyle-update-modify-plot-containing-frames/5553
# https://plot.ly/javascript/animations/#frame-groups-and-animation-modes
# https://plot.ly/javascript/animations/
if (input$add){
cat("add trace\n")
my$fnumber <- my$fnumber + 1
my$ntraces <- my$ntraces + 2
f <- as.character(my$fnumber)
x <- runif(2)
y <- rep(runif(1), 2)
t <- c("A", "B")
ids0 <- paste0(my$ntraces-2, letters[1:2])
ids1 <- paste0(my$ntraces-1, letters[1:2])
my$frame$name <- f
my$frame$data[[my$ntraces-1]] <- list(x=x, y=y, frame=f, ids=ids0, type="scatter", mode="lines", showlegend=FALSE)
my$frame$data[[my$ntraces-0]] <- list(x=x, y=y, frame=f, ids=ids1, type="scatter", mode="text", text=t, showlegend=FALSE)
my$frame$traces <- as.list(as.integer(1:my$ntraces - 1))
plotlyProxyInvoke(proxy, "addTraces",
list(
my$frame$data[[my$ntraces-1]],
my$frame$data[[my$ntraces-0]]
))
plotlyProxyInvoke(proxy, "animate",
# frameOrGroupNameOrFrameList
list(
name = my$frame$name,
data = my$frame$data,
traces = my$frame$traces
),
# animationAttributes
list(
frame=list(duration=0),
transition=list(duration=0)
)
)# animate
}
if (input$animate){
cat("animate traces\n")
my$fnumber <- my$fnumber + 1
f <- as.character(my$fnumber)
traces <- 1:my$ntraces - 1
for (i in seq(0, my$ntraces-2, 2)){
x <- runif(2)
y <- rep(runif(1), 2)
t <- c("A", "B")
ids0 <- paste0(i, letters[1:2])
ids1 <- paste0(i+1, letters[1:2])
my$frame$data[[i+1]] <- list(x=x, y=y, frame=f, ids=ids0, type="scatter", mode="lines", showlegend=FALSE)
my$frame$data[[i+2]] <- list(x=x, y=y, frame=f, ids=ids1, type="scatter", mode="text", text=t, showlegend=FALSE)
}
my$frame$name <- f
plotlyProxyInvoke(proxy, "animate",
# frameOrGroupNameOrFrameList
list(
name = my$frame$name,
data = my$frame$data,
traces = my$frame$traces
),
# animationAttributes
list(
frame=list(duration=speed),
transition=list(duration=speed)
)
)# animate
}
if (input$rescale){
cat("animate layout\n")
my$fnumber <- my$fnumber + 1
f <- as.character(my$fnumber)
my$xrange <- runif(2)*0.1+c(-0.1,1)
my$frame$name <- f
my$frame$layout <- list(xaxis=list(range=my$xrange))
plotlyProxyInvoke(proxy, "animate",
# frameOrGroupNameOrFrameList
list(
name = my$frame$name,
data = my$frame$data,
traces = my$frame$traces,
layout = my$frame$layout
),
# animationAttributes
list(
frame=list(duration=speed),
transition=list(duration=speed)
)
) # animate
}
}) # observeEvent
}
shinyApp(ui, server)