Avoid double plot refresh on data reload

My shiny application allows the user to upload a time series data file, and then select which variables to plot (ggplot) using a checkboxGroupInput. When I load a new file, I want to clear the checkbox selections and just draw an empty plot until the user selects variables again. Unfortunately, what actually happens is the plot redraws briefly using the old selection, then clears the selections and draws the empty plot. I have a reprex below, to reproduce, load file1.csv, choose a variable to plot, and then load file2.csv, you'll see the different data from file2 pop on the screen briefly and then disappear.

I'd appreciate any tips here... I feel this is a simple reactive thing but everything I've tried hasn't worked. I'm not sure if it's complicating things, but I have the plot and checkbox hidden in a conditional panel until the file is loaded... my real application has more stuff that is hidden as well. Thanks in advance for any help on this particular issue, or any tips you have about my code in general!

library(shiny)
library(tidyverse)

# create example data files to use for loading
write_csv(data.frame(time=1:10,var1=sample(1:10),var2=sample(1:10)),"file1.csv")
write_csv(data.frame(time=1:10,var1=sample(1:10),var2=sample(1:10)),"file2.csv")

ui <- fluidPage(
  fileInput("logfile", "Choose data file", multiple = FALSE),
  
  conditionalPanel("output.fileUploaded",
                     plotOutput('plot'),
                     checkboxGroupInput("variables",label="Variables to Plot")
  )
)

server <- function(input, output, session) {
  df <- reactive({
    req(input$logfile)
    read_csv(input$logfile$datapath) %>% pivot_longer(-time)
  })
  
  output$fileUploaded <- reactive({
    updateCheckboxGroupInput(session, "variables", "Variables to show",
                             unique(df()$name))
    return(!is.null(df()))
  })
  
  outputOptions(output, 'fileUploaded', suspendWhenHidden=FALSE)
  
  output$plot <- renderPlot({
    ggplot(filter(df(),name %in% input$variables),aes(x=time,y=value)) +
      geom_line(aes(col=name)) 
  })
}

shinyApp(ui = ui, server = server)

I found this SO post which I think has a lot of similarities to my problem. Their discussion of it seeming like some kind of race condition is how it appears to me too. I also tried their idea of setting a boolean variable like "isUpdating" and then trying to make the plotting only occur when it is false, but it does not work for some reason.

Is this what you are looking for?

library(shiny)
library(tidyverse)

# create example data files to use for loading
write_csv(data.frame(time=1:10,var1=sample(1:10),var2=sample(1:10)),"file1.csv")
write_csv(data.frame(time=1:10,var1=sample(1:10),var2=sample(1:10)),"file2.csv")

ui <- fluidPage(
  fileInput("logfile", "Choose data file", multiple = FALSE),
  
  conditionalPanel("output.fileUploaded",
                   plotOutput('plot'),
                   checkboxGroupInput("variables",label="Variables to Plot")
  )
)

server <- function(input, output, session) {
  df <- reactive({
    req(input$logfile)
    read_csv(input$logfile$datapath) %>% pivot_longer(-time)
  })
  
  output$fileUploaded <- reactive({
    updateCheckboxGroupInput(session, "variables", "Variables to show",
                             unique(df()$name))
    return(!is.null(df()))
  })
  
  outputOptions(output, 'fileUploaded', suspendWhenHidden=FALSE)
  
  PlotDat <- eventReactive(input$variables, filter(df(),name %in% input$variables))
  output$plot <- renderPlot({
    ggplot(PlotDat() ,aes(x=time,y=value)) +
      geom_line(aes(col=name)) 
  })
  
}

shinyApp(ui = ui, server = server)

Yes, I think that is it! Thanks! It works on my reprex. For my full application I have a few more reactives linking things together that I need to deal with... but hopefully the same approach will work. If not I'll post back here.

In general I find it hard to keep track of the reactive chains that get created when writing Shiny apps... not sure if it's supposed to be more obvious or if there is a more structured way to keep track.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.