Wednesday, November 8, 2017

Redraw plot once if one reactive value changes but not the other?

Leave a Comment

I have two reactive values input$code and input$variants and I want to redraw the plot once if any of the following conditions are true.

  1. code changes and variants changes
  2. code changes and variants does not change
  3. code does not change and variants changes

I can't call both input$code and input$variants in renderPlotly or else the plot will get redrawn twice for #1 above.


  output$choose_test <- renderUI({     data_sets <- loadTest()     selectizeInput(       'test', 'Test', choices = data_sets$test, selected = data_sets$test[1]     )   })    output$choose_code <- renderUI({     validate(       need(input$test, 'Please choose a test.')     )      code <- loadCode(input$test)     selectizeInput(       'code', 'Code', choices = code$code, selected = code$code[1]     )   })    output$choose_variants <- renderUI({     validate(       need(input$test,  'Please choose a test.'),       need(input$code,   'Please choose a code.')     )      dat <- loadVariants(input$test, input$code)      default_select <- dat$variant[grep('v1|v2', dat$variant)]     if (identical(default_select, factor(0))) {       default_select <- dat$variant[1]     }      checkboxGroupInput("variants", "Variants",                         choices  = dat$variant,                         selected = default_select)   })    output$plot1 <- renderPlotly({      runLocations <- isolate(loadRunsBetweenDates(input$test, input$code, input$variants))      total_min_df <-       runLocations %>%       group_by(change_number, variant) %>%       summarize(memory = min(memory))      total_min_df$change_number <- as.numeric(as.character(total_min_df$change_number))      p <- ggplot(total_min_df,            aes(x=change_number,                y=memory,                group=variant,                color=variant))+     geom_point()+     geom_smooth(se = FALSE)+     scale_x_continuous(labels = function(n){format(n, scientific = FALSE)})+     scale_y_continuous(labels = function(n){format(n, scientific = FALSE)})+     labs(x = "Change Number", y = "Megabytes")      ggplotly(p)   }) 

1 Answers

Answers 1

From what i see your input$test, potentially triggers an update in input$code. That results in the problem that a change in input$test can trigger your described "double update".

What you can do is make a single trigger, that you store e.g. in a reactive value global$updatePlot and make the update in the plot solely dependent on that variable (with isolate, see code).

Now, you also have to make sure that not only the trigger only fires once but also only fires if the potential update in input$code is ready.

It could work as provided below, but as the others wrote without a reproducible example its hard to be sure ;)

# new code here observe({   validate(     need(input$test, 'Please choose a test.'),     need(input$variants, 'Please choose a variant.')   )   input$variants   global$code <- loadCode(input$test)   # now global$code triggered potential new input$code and we can give trigger the plot update   global$updatePlot <- rnorm(1) })  #changed code here output$choose_code <- renderUI({   code <- global$code   selectizeInput(     'code', 'Code', choices = code$code, selected = code$code[1]   ) })  # store the trigger for plot update if inputs changed global <- reactiveValues(updatePlot = TRUE)  output$plot1 <- renderPlotly({   # update plot only with a single trigger.   global$updatePlot   isolate({     validate(       need(input$test, 'Please choose a test.'),       need(input$variants, 'Please choose a variant.'),       need(input$code, 'Please choose a code.')     )     runLocations <- isolate(loadRunsBetweenDates(input$test, input$code, input$variants))      total_min_df <-       runLocations %>%       group_by(change_number, variant) %>%       summarize(memory = min(memory))      total_min_df$change_number <- as.numeric(as.character(total_min_df$change_number))      p <- ggplot(total_min_df,                 aes(x=change_number,                     y=memory,                     group=variant,                     color=variant))+       geom_point()+       geom_smooth(se = FALSE)+       scale_x_continuous(labels = function(n){format(n, scientific = FALSE)})+       scale_y_continuous(labels = function(n){format(n, scientific = FALSE)})+       labs(x = "Change Number", y = "Megabytes")      ggplotly(p)       })  }) 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment