Search code examples
rvalidationresizewindowshiny

R Shiny with validate: Plot only refreshes after resizing window


I'm trying to use validate() in Shiny, but I keep encountering an issue every time the validation command finds an error. I'm trying to plot something where occasionally some subcategory of data might not have any values (i.e. if the categories are colors, you can select "green", but sometimes the dataset will not contain any rows in category "green").

Whenever the condition I'm validating comes back as false, the error message prints correctly. However, when I then re-select a new value and update, the new plot only appears after I manually resize the window, as opposed to appearing as it normally would after I click "update".

colors = c("green","blue","red")
library(shiny)

ui <- fluidPage(

  tabsetPanel(
    tabPanel("Info",
             selectInput(inputId = "color",label = "color:",
                         choices = colors,
                         selected = colors[2],
                         multiple = FALSE),
             actionButton(inputId = "go",
                          label = "Update"),
             plotOutput("plot", width = "100%", height = 700,
                        brush = brushOpts(id = "plot_brush",fill = "green",clip = FALSE))

    )
  )
)

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

  data = eventReactive(input$go, {
    var1 = rnorm(20,5)
    cat1 = (c(rep("red",10),rep("blue",10)))
    data = cbind.data.frame(var1,cat1)
    plotdata = data[which(data$cat1 ==isolate(input$color)),]

  }
  )

  output$plot = renderPlot({

    validate(
      need(  (isolate(input$color) %in% c("red","blue"))  , "No color of this type " )
    )

    plotdata = data()
    plot(plotdata$var1, col = isolate(input$color)) 
  })
}

shinyApp(ui = ui,server = server)

FYI I'm using Shiny version 0.13.1, R version 3.2.3


Solution

  • The issue is that input$color is wrapped in isolate in your need statement. So the need still thinks that you have chosen the wrong color because nothing tells it to recheck input$color. If you add input$go as the first line of your renderPlot (just before the validate) I think it does what you want.