Takkun
Takkun

Reputation: 6361

How to prevent shiny plot from being redrawn multiple times per UI interaction?

In my shiny app I have a date range input and a group of checkboxes. The checkbox choices are determined based on the input$dateRange. I'm running into an issue where the plot is being redrawn twice every time the date range is changed. The first time it is redrawn it will use the new date ranges, but the old checkbox choices. Then the checkbox choices are updated and the plot is redrawn a second time.

Is there any way to prevent redrawing the plot multiple times and only have it drawn once all the other UI elements have updated?

server.R code snippet

  # Check boxes for variants in run
  output$choose_variants <- renderUI({
    # Get the variants associated with the run
    dat <- loadVariants(input$dateRange[1], input$dateRange[2])
    if(is.null(dat))
      return()

    # Create the checkboxes and select them all by default
    checkboxGroupInput("variants", "Variants",
                        choices  = dat$variant,
                        selected = dat$variant)
  })

  # Output the data
  output$plot1 <- renderPlot({
    runLocations <- loadRunsBetweenDates(input$dateRange[1], input$dateRange[2], input$variants)
    #ggplot()
  })

ui.R code snippet

  sidebarPanel(
    dateRangeInput('dateRange',
      label = 'Date range',
      start = Sys.Date(), end = Sys.Date()
    ),
    uiOutput("choose_variants")
  ),

Upvotes: 4

Views: 1001

Answers (1)

Florian
Florian

Reputation: 25385

Since input$variants always changes whenever the date range slider changes, you can make your plot dependent on input$variants only.

  # Output the data
  output$plot1 <- renderPlot({

    # outside of isolate statement, so this plot becomes dependent on its value.
    input$variants

    # put this in an isolate block, so it doesn´t trigger an invalidation.
    isolate(runLocations <- loadRunsBetweenDates(input$dateRange[1], input$dateRange[2], input$variants))
    #ggplot()
  })

Hope this helps!

EDIT: Alternative, based on condition in comment

You could create a reactive, and make your plot only dependent on that as follows:

  loadedVariants <- reactive({
  loadVariants(input$dateRange[1], input$dateRange[2])
  })

 # Output the data
  output$plot1 <- renderPlot({

    # outside of isolate statement, so this plot becomes dependent on its value.
    loadedVariants()

    # put this in an isolate block, so it doesn´t trigger an invalidation.
    isolate(runLocations <- loadRunsBetweenDates(input$dateRange[1], input$dateRange[2], input$variants))
    #ggplot()
  })

Upvotes: 3

Related Questions