Open saggrawal76 opened 2 years ago
I haven't solved your issue, but I think I improved your reprex, by simplifying it down of library dependencies, etc.
library(shiny)
library(plotly)
library(ggplot2)
siderbar <- dashboardSidebar(
sidebarMenu()
)
ui <- fluidPage(sidebarLayout(
sidebarPanel(
# Add buttons to choose the way you want to select your data
selectInput(inputId = "inp_species", label = "Select by:",
choices = c("setosa", "versicolor", "virginica"), selected = "setosa"),
radioButtons(
inputId = "radioTest", label = "Choose one:",
choices = c(
"Simple Plot" = "simple",
"Plotly" = "plotly"
),
inline = FALSE, selected = "simple"
)
),mainPanel(
fluidRow(
column(
6,
uiOutput("tabset1Selected")
)
),
fluidRow(
column(6, plotlyOutput("plot1x")),
column(6, plotOutput("plot2x"))
)))
)
shinyApp(
ui = ui,
server = function(input, output, session) {
iris_dt <- reactive({
subset(x = iris,
Species == input$inp_species)
})
p1 <- reactive({
plot_ly(req(iris_dt()), x = ~Petal.Width, y = ~Sepal.Length,type = "scatter",
mode="markers")
})
output$plot1 <- output$plot1x <- renderPlotly({
req(p1())
})
p2 <- reactive({
ggplot(req(iris_dt()), aes(x = Petal.Width, y = Sepal.Length)) +
geom_point()
})
output$plot2 <- output$plot2x <- renderPlot({
req(p2())
})
# The currently selected tab from the first box
output$tabset1Selected <- renderUI({
switch(EXPR = req(input$radioTest),
"plotly" = plotlyOutput("plot1"),
"simple" = plotOutput("plot2")
)
})
}
)
Thanks, @nir4most. I have checked your code and the rendering has improved. The cache issue is still persistent.
I don't think this is a cache issue.
This is a matter of the output's visibility. Usually in shiny an output will only be updated if it is visible (this saves resources).
Accordingly when you switch from a freshly updated ouput to a previously hidden ouput, it is still in its old state (for a short time).
You can avoid this by using outputOptions(output, "myplot", suspendWhenHidden = FALSE)
Here is an example (also avoiding renderUI
- personal preference):
library(shiny)
library(plotly)
library(ggplot2)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "inp_species",
label = "Select by:",
choices = c("setosa", "versicolor", "virginica"),
selected = "setosa"
),
radioButtons(
inputId = "radioTest",
label = "Choose one:",
choices = c("Simple Plot" = "simple",
"Plotly" = "plotly"),
inline = FALSE,
selected = "simple"
)
),
mainPanel(fluidRow(
column(
6,
conditionalPanel("input.radioTest == 'simple'", plotOutput("plot2")),
conditionalPanel("input.radioTest == 'plotly'", plotlyOutput("plot1"))
)
),
fluidRow(
column(6, plotlyOutput("plot1x")),
column(6, plotOutput("plot2x"))
))
)
)
server <- function(input, output, session) {
iris_dt <- reactive({
subset(x = iris, Species == input$inp_species)
})
output$plot1 <- output$plot1x <- renderPlotly({
# Sys.sleep(2L)
plot_ly(
req(iris_dt()),
x = ~ Petal.Width,
y = ~ Sepal.Length,
type = "scatter",
mode = "markers"
)
})
output$plot2 <- output$plot2x <- renderPlot({
# Sys.sleep(2L)
ggplot(req(iris_dt()), aes(x = Petal.Width, y = Sepal.Length)) +
geom_point()
})
lapply(list("plot1", "plot2"), outputOptions, x = output, suspendWhenHidden = FALSE)
}
shinyApp(ui, server)
Thanks @ismirsehregal. Using outputOptions(output, "myplot", suspendWhenHidden = FALSE)
is not solving this issue. In my real app, it just takes too much time to execute all possible outputs in the background and honestly, I won't need all the rendering in the background until the user clicks on the radio button. I am looking for a more intuitive solution so that when a user switches from a freshly updated output to a previously hidden output, the old state is hidden until the new state is refreshed.
@saggrawal76 Just so I understand the symptom, with the reprex you posted, the behavior I'm seeing is that the "stale" plot appears for just a fraction of a second and then is replaced by the correct plot. In your real app, do the calculations take a lot longer so the stale plot appears for a few seconds? And if that's so, does the stale plot at least become semi-transparent while Shiny is thinking?
@jcheng5 You are correct, the calculations take a few seconds and the "stale" plot appears during that time. The stale plot does not 'blur' during the waiting period. This behavior causes confusion while using the app.
@saggrawal76 - ok sorry - so the example was misleading. Maybe you can reproduce the error by calling e.g. Sys.sleep(2L)
in renderPlot
/ renderPlotly
?
@ismirsehregal - I have implemented your suggested code (without RenderUI
function) and added Sys.sleep(2L)
in the example code. It now exactly reproduces the error. FYI.. the same problem exists in the RenderUI
version too.
System details
Browser Version: Chrome - Version 104.0.5112.81 (Official Build) (64-bit)
Output of
sessionInfo()
:Example application or steps to reproduce the problem
```R # Minimal, self-contained example app code goes here library(shiny) library(shinydashboard) library(shinyWidgets) library(plotly) library(ggplot2) library(data.table) siderbar <- dashboardSidebar(sidebarMenu()) ui <- fluidPage( sidebarLayout( sidebarPanel( selectInput( inputId = "inp_species", label = "Select by:", choices = c("setosa", "versicolor", "virginica"), selected = "setosa" ), radioButtons( inputId = "radioTest", label = "Choose one:", choices = c("Simple Plot" = "simple", "Plotly" = "plotly"), inline = FALSE, selected = "simple" ) ), mainPanel(fluidRow( tabPanel( 6, conditionalPanel("input.radioTest == 'simple'", plotOutput("plot2")), conditionalPanel("input.radioTest == 'plotly'", plotlyOutput("plot1")) ) ) ) ) ) server <- function(input, output, session) { iris_dt <- reactive({ subset(x = iris, Species == input$inp_species) }) output$plot1 <- output$plot1x <- renderPlotly({ Sys.sleep(2L) plot_ly( req(iris_dt()), x = ~ Petal.Width, y = ~ Sepal.Length, type = "scatter", mode = "markers" ) }) output$plot2 <- output$plot2x <- renderPlot({ Sys.sleep(2L) ggplot(req(iris_dt()), aes(x = Petal.Width, y = Sepal.Length)) + geom_point() }) } shinyApp(ui, server) ``` ### Describe the problem in detail I created a Shiny app, in which I am drawing a scatter plot on iris dataset using libraries highchart, ggplot and plotly. When I dynamically render the UI using a graphical library (such as highchart), then for the first time rendering works as expected. But when I select a different graphical library, then the cache of older graphical library renders (for a while) before the newly selected graphical library can draw. Here is the complete list of steps to reproduce this problem. Example code is shared. I am selecting the library to draw the chart dynamically using a selectInput box. Here is the problem - 1. I select a species in selectInput box and the highchart library draws a scatter plot 2. Then I select plotly in the radio button section and the rendering is done using plotly. 3. I change the species in selectInput and plotly re-renders the plot 4. Now, when I click on highchart radio button, the plot of the earlier species (from cache) is drawn for a few seconds and then the chart of the selected species is drawn.