Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
558 views
in Technique[技术] by (71.8m points)

Can I programmatically control plotly zoom functionality without having to re-plot in an R shiny app?

I am trying to make a shiny app in R using Plotly plots. I am trying to create zoom functionality in the backend of a shiny app, responsive to a click event on a plotly graph (i.e. when a point is clicked, zoom in on that point). However, the only solution I have found so far is to completely re-layout the plotly object with new view ranges.

For large plots, this is incredibly slow because shiny re-renders the entire plot, and is much slower than plotly's built-in zoom functionality on the front end (the plotly user interface buttons at the top right) when the number of data points is large. Is there a way to use the plotly zoom functionality in the backend so that the whole plotly object doesn't have to re-render to zoom?

Example:

library(plotly)
library(shiny)

ui <- fluidPage(
  plotlyOutput("scatter")
)
server <- function(input, output) {
  zoom_vals = reactiveValues(xrange=NA,yrange=NA)
  # Plot scatter plot
  output$scatter <- renderPlotly({
    data <- data.frame(x=sample.int(1000,100), y = sample.int(1000,100))
    x_axis = list(range = zoom_vals$xrange)
    y_axis = list(range = zoom_vals$yrange)
    plot_ly(data, x = ~x, y = ~y) %>% layout(xaxis=x_axis, yaxis=y_axis)
  })
  # Catch plot click
  observeEvent(event_data("plotly_click"),{
    d<-event_data("plotly_click")
    zoom_vals$xrange <- c((d$x- 1),(d$x+ 1))
    zoom_vals$yrange <- c((d$y- 1),(d$y- 1))
  })
}
shinyApp(ui, server)
question from:https://stackoverflow.com/questions/65907768/can-i-programmatically-control-plotly-zoom-functionality-without-having-to-re-pl

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can modify (no re-rendering) an exisiting plotly object in shiny via plotlyProxyInvoke.

To change the axis range we'll need the relayout method:

library(plotly)
library(shiny)

ui <- fluidPage(plotlyOutput("scatter"))

server <- function(input, output) {
  # Plot scatter plot
  output$scatter <- renderPlotly({
    data <- data.frame(x = sample.int(1000, 100), y = sample.int(1000, 100))
    plot_ly(data, x = ~ x, y = ~ y, type = "scatter", mode = "markers")
  })
  
  scatterProxy <- plotlyProxy("scatter")
  
  # Catch plot click
  observeEvent(event_data("plotly_click"), {
    d <- event_data("plotly_click")
    xrange <- c((d$x - 100), (d$x + 100))
    yrange <- c((d$y - 100), (d$y + 100))
    plotlyProxyInvoke(scatterProxy, "relayout", list(xaxis = list(range = xrange), yaxis = list(range = yrange)))
  })
}

shinyApp(ui, server)

result


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...