Why did reactive expression only fire once? We do not see the fourth graph with the same reactive expression

library(shiny)

#--------------- some function for investigation
mfun <- function(x) {return((x + 3)^2 * sin(x - 2))}

#-------------------------
ui <- fluidPage(
   # -- set range for plot
   numericInput(inputId = 'xmin',  label = 'x left',  value = 0),
   numericInput(inputId = 'xmax',  label = 'x right', value = 15),

   # -- first plot 
   plotOutput(outputId = 'plot_1',  width = '80%',  height = '200px'),

   # -- second plot 
   plotOutput(outputId = 'plot_2',  width = '80%',  height = '200px'),

   # -- third plot 
   plotOutput(outputId = 'plot_3',  width = '80%',  height = '200px'),
   
   # -- fourth plot - why is the graph not displayed ??? 
   plotOutput(outputId = 'plot_4',  width = '80%',  height = '200px')
)

#=================================
server <- function(input, output) {
  
  #----- define points for plot() 
  xgr <- reactive({seq(
      from = input$xmin,
      to = input$xmax,
      by = (input$xmax - input$xmin) / 5)
  })

  #---- the repeated code is rendered into a reactive expression
  basePlot <- reactive({
    plot(x = xgr(),
         y = mfun(xgr()),
         type = 'l',
         lwd = 3,
         col = 'red')    
  })
  
  #--- draw plot with explicit call plot() - it's OK
  output$plot_1 <- renderPlot(expr = {
    plot(x = xgr(),
         y = mfun(xgr()),
         type = 'l',
         lwd = 3,
         col = 'red')
  }, res = 50)
  
  
  #--------- draw plot with explicit call plot() and abline() - it's OK
  output$plot_2 <- renderPlot(expr = {
    plot(x = xgr(),
         y = mfun(xgr()),
         type = 'l',
         lwd = 3,
         col = 'red')

    abline(h = mfun(xgr()), v = xgr(), col = 'gray', lwd = 0.5, lty = 2)
    },  res = 50)  

  
  #--------- draw plot with reactive basePlot() - it's OK
  output$plot_3 <- renderPlot(expr = {
     basePlot()
  }, res = 50)
  
  #--------- draw plot with reactive basePlot() - it's NOT OK !!
  output$plot_4 <- renderPlot(expr = {
    basePlot()

    abline(h = mfun(xgr()), v = xgr(), col = 'gray', lwd = 0.5, lty = 2)
  },  res = 50)  
}

shinyApp(ui = ui, server = server)

Hello @Korall,

I managed to get the 4th to display by turning your basePlot() reactive function into a regular function and passing the reactive values in it.

The R plotting functions relies on side effects to accumulate on top of each other and in the 4th chart the initial plot and the abline are defined in separate reactive scopes.

library(shiny)

#--------------- some function for investigation
mfun <- function(x) {return((x + 3)^2 * sin(x - 2))}

#-------------------------
ui <- fluidPage(
   # -- set range for plot
   numericInput(inputId = 'xmin',  label = 'x left',  value = 0),
   numericInput(inputId = 'xmax',  label = 'x right', value = 15),

   # -- first plot 
   plotOutput(outputId = 'plot_1',  width = '80%',  height = '200px'),

   # -- second plot 
   plotOutput(outputId = 'plot_2',  width = '80%',  height = '200px'),

   # -- third plot 
   plotOutput(outputId = 'plot_3',  width = '80%',  height = '200px'),
   
   # -- fourth plot - why is the graph not displayed ??? 
   plotOutput(outputId = 'plot_4',  width = '80%',  height = '200px')
)

#=================================
server <- function(input, output) {
  
  #----- define points for plot() 
  xgr <- reactive({seq(
      from = input$xmin,
      to = input$xmax,
      by = (input$xmax - input$xmin) / 5)
  })

  #---- the repeated code is rendered into a reactive expression
  basePlot <- function(xgr) {
      plot(x = xgr,
         y = mfun(xgr),
         type = 'l',
         lwd = 3,
         col = 'red')  
  }
  
  #--- draw plot with explicit call plot() - it's OK
  output$plot_1 <- renderPlot(expr = {
    plot(x = xgr(),
         y = mfun(xgr()),
         type = 'l',
         lwd = 3,
         col = 'red')
  }, res = 50)
  
  
  #--------- draw plot with explicit call plot() and abline() - it's OK
  output$plot_2 <- renderPlot(expr = {
    plot(x = xgr(),
         y = mfun(xgr()),
         type = 'l',
         lwd = 3,
         col = 'red')

    abline(h = mfun(xgr()), v = xgr(), col = 'gray', lwd = 0.5, lty = 2)
    },  res = 50)  

  
  #--------- draw plot with reactive basePlot() - it's OK
  output$plot_3 <- renderPlot(expr = {
     basePlot(xgr())
  }, res = 50)
  
  #--------- draw plot with reactive basePlot() - it's NOT OK !!
  output$plot_4 <- renderPlot(expr = {
    basePlot(xgr())
    abline(h = mfun(xgr()), v = xgr(), col = 'gray', lwd = 0.5, lty = 2)
  },  res = 50)  
}

shinyApp(ui = ui, server = server)

Thanks a lot!
Apparently, ordinary functions are more universal and reliable, and it is better to implement the code through them.

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

If you have a query related to it or one of the replies, start a new topic and refer back with a link.