r - 使用 plotlyProxyInvoke 组合闪亮的情节动画时轴重置
问题描述
我正在尝试制作一个动画情节,其中引入了新的痕迹,对痕迹进行了动画处理,然后重新调整了轴的比例。我很难让这些东西一起工作。下面是一个代表。它可以工作,除非我同时拥有动画跟踪和重新缩放轴,然后轴重新缩放在每次迭代时都会重置。
https://community.plot.ly/t/how-to-efficiently-restyle-update-modify-plot- contains-frames/5553
https://plot.ly/javascript/plotlyjs-function-reference/
https://plot.ly/javascript/animations/
遵循 Plotly 文档相当困难。我无法让 addFrames、relayout、restyle、react 或 update 为我工作。我在动画方面最幸运。我将不胜感激任何帮助,我已经为此苦苦挣扎了两个星期。
# 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)
解决方案
推荐阅读
- c# - 将日期时间存储在天蓝色表存储中
- rust - 如何将 crypto::sha2::Sha256 哈希转换为 &[u8] 表示?
- stargazer - Stargazer 在负数值的减号周围加上额外的 $...$
- css - 使用 Angular-CLI 进行 CSS 优化后处理
- ios - React Native标签栏闪烁
- jquery - 隐藏已附加内容的问题
- python - Matplotlib 自定义样式:不同的刻度颜色和刻度标签颜色
- swift - 将 Firestore 数据显示到 UIPicker Swift 4
- python - 通过python仅从txt文件中提取特定文本
- wordpress - Woocommerce 自定义文本区域的文本域