I have an animated plot where data changes should trigger changes in the axis scaling and trace colouring. How do I get these things to occur in a smooth sequence? I want the bars to move, then the axis to change, then the color to change, without having any user intervention. A manual version of what I want is below. When I put all the proxy calls together I lose all the animations. Thanks.
library(shiny)
library(plotly)
library(dplyr)
ui <- fluidPage(
actionButton("move", "Click to animate"),
actionButton("stretch", "Click to rescale"),
actionButton("recolour", "Click to recolour"),
plotlyOutput("plot")
)
gendata <- function(){
ndata <- 10
d <- tibble(text=LETTERS[1:ndata], f=1, x=runif(ndata)) %>% mutate(r = rank(x))
rbind(mutate(d, x=-1), d, mutate(d, x=-1)) %>%
arrange(text)
}
server <- function(input, output, session){
origdata <- gendata()
if (FALSE){ # for offline testing
print(head(origdata))
my <- list(olddata = origdata, newdata = origdata)
}
my <- reactiveValues(
olddata = origdata,
newdata = origdata,
xrange = list(0,1.1)
)
output$plot <- renderPlotly({
cat("renderPlotly\n")
plot_ly() %>%
add_trace(x=origdata$x, y=origdata$r, frame=origdata$f, line=list(width=20, simplify=FALSE), type="scatter", opacity=0.3, color=I("green"), mode="lines", name="Rank") %>%
add_trace(x=origdata$x + 0.02, y=origdata$r, frame=origdata$f, text=origdata$text, type="scatter", mode="text", showlegend=FALSE) %>%
layout(xaxis=list(range=isolate(my$xrange))) %>%
animation_opts(frame=500, transition=500, redraw=FALSE)
})
proxy <- plotlyProxy("plot", session=session, deferUntilFlush=FALSE)
observeEvent(input$move, {
req(my$newdata)
cat("observeEvent input$move\n")
my$olddata <- my$newdata # save old data
my$newdata <- gendata() %>% # generate new data
mutate(f=my$olddata$f+1)
my$xrange <- list(-runif(1)*0.1, 1+runif(1)*0.1) # new range also
print(head(my$newdata))
# https://plot.ly/javascript/plotlyjs-function-reference/#plotlyanimate
plotlyProxyInvoke(proxy, "animate",
# frameOrGroupNameOrFrameList
list(
data = list(list(
x = my$newdata$x,
y = my$newdata$r,
frame = my$newdata$f
),
list(
x = my$newdata$x + 0.02,
y = my$newdata$r,
text = my$newdata$text,
frame = my$newdata$f
)),
traces = list(as.integer(0), as.integer(1)),
layout = list()
),
# animationAttributes
list()
)# plotlyProxyInvoke
})
observeEvent(input$stretch, {
plotlyProxyInvoke(proxy, "relayout",
# update
list(
xaxis=list(range=my$xrange)
)
)
})
observeEvent(input$recolour, {
plotlyProxyInvoke(proxy, "restyle",
# update
list(
line=list(width=20, simplify=FALSE, color=sample(c(I("red"), I("green"), I("blue")), 1))
),
# tradeIndices
list(as.numeric(0))
)
})
}
shinyApp(ui, server)