Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update plotly in R without recreating widget when plotted data is altered

Everytime a plotly object is created by R in shiny, (or just in R), the widget is recreated completely. For small data sets this is not a problem, but i'm working with plots that contain thousands of scatter points, making it take 10-20 seconds to recreate a plot in my shinyapp.

I'm looking for a way to update the data through a javascript solution that doesn't trigger the widget to be rebuild, but simply replaces it's data.

Here is a dummy app with 2 small data sets between which the app can switch. In the dummy app it does it by recreating the widget. Quite fast here due to the limited datapoints, but not ideal for massive data sets.

If anyone knows how to accomplish this, it would be a major improvement for my app.

TO CLARIFY: An answer like this one here: enter link description here won't do the trick for me. The point is, in my app data is changed many times AFTER the plot has been build so I can't pre-load a list of data frames.

I have the feeling the solution would have to be a javascript solution that can grab the data to overwrite the currently plotted data, but not sure how or whether this can be done.

library("shiny")
library("plotly")

ui <- fluidPage(
  selectInput("dataset", "Choose a dataset:", choices = c("rock", "mtcars")),

  plotlyOutput("Plot1")
)


server <- function(input, output, session) {

  dataSource <- reactive({switch(input$dataset,"rock" = rock,"mtcars" = mtcars)})

  output$Plot1 <-  renderPlotly({plot_ly(data = dataSource(), x = dataSource()[,1], 
                                         y =dataSource()[,2], mode = 'markers', type = 'scatter')})
}

shinyApp(ui, server)
like image 268
Mark Avatar asked May 12 '18 09:05

Mark


1 Answers

Take a look at these resources that might be useful to your case:

  1. Plotly R book by Carson Sievert chapters 3, 4 & 6
  2. Plotly proxy function explanation

This is the code to get you started. You have a bit of work to adjust the axis labels but this should not be that difficult.

Hope this helps!

The code:

    library("shiny")
    library("plotly")

    ui <- fluidPage(
            selectInput("dataset", "Choose a dataset:", choices = c("rock", "mtcars")),

            plotlyOutput("Plot1")
    )


    server <- function(input, output, session) {

            dataSource <- reactive({switch(input$dataset,"rock" = rock,"mtcars" = mtcars)})

            output$Plot1 <-  renderPlotly({plot_ly(data = rock, x = ~area, 
                                                   y =~peri, mode = 'markers', type = 'scatter')})

            observeEvent(input$dataset, {
                    f <- list(
                            family = "Courier New, monospace",
                            size = 18,
                            color = "#7f7f7f"
                    )
                    x <- list(
                            title = "x Axis",
                            titlefont = f, 
                            range = c(0, 1000)
                    )
                    y <- list(
                            title = "y Axis",
                            titlefont = f,
                            range = c(0, 100)
                    )
                    plotlyProxy("Plot1", session) %>%
                            plotlyProxyInvoke("addTraces", list(x = dataSource()[,1], 
                                                                y = dataSource()[,2],
                                                                type = 'scatter',
                                                                mode = 'markers')) %>% 
                            plotlyProxyInvoke("deleteTraces", list(as.integer(0))) %>% 
                            plotlyProxyInvoke("relayout", list(xaxis = x, yaxis = y))
            })



    }

    shinyApp(ui, server)
like image 61
Valter Beaković Avatar answered Oct 21 '22 13:10

Valter Beaković