I have a shiny app in which the plot needs to adjust in height based on user input. Basically, the plot could have one, two, or four sub-plots. Everything is fine when there are one or two, but with four, the subplots get squashed to a too small size. I've tried to use a reactive function to give me a calculated height with the server, but I get this error:
Error in .getReactiveEnvironment()$currentContext() : 
  Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
A very simplified version of what I'm attempting to do is here:
library(shiny)
ui <- fluidPage(
   fluidRow(
      column(2, 
             radioButtons( inputId = 'plotcount', label = 'Plot Count', 
                                 choices = c('1' = 1, 
                                             '2' = 2,
                                             '4' = 4
                                 ),
                           selected = '1'
             )
      ),
      column(10, 
             plotOutput( outputId = 'plots' )
      )
   )
)
server <- function(input, output) {
   PlotHeight = reactive(
      return( 500+250*(floor(input$plotcount/4)))
   )
   output$plots = renderPlot(height = PlotHeight(), {
      if( as.numeric(input$plotcount) == 0 ){
         plot.new()
         return()
      }
      print(c( floor(sqrt(as.numeric(input$plotcount))),
               ceiling(sqrt(as.numeric(input$plotcount)))
      ))
      opar = par( mfrow = c( floor(sqrt(as.numeric(input$plotcount))),
                             ceiling(sqrt(as.numeric(input$plotcount)))
                             )
                  )
      for( i in 1:as.numeric(input$plotcount) ){
         plot(1:100, 1:100, pch=19)
      }
      par(opar)
   })
}
shinyApp(ui =ui, server = server)
                Use renderUI:
library(shiny)
ui <- fluidPage(
  fluidRow(
    column(
      width = 2
      , radioButtons(
          inputId = 'plotcount'
        , label   = 'Plot Count'
        , choices = as.character(1:4)
      )
    ),
    column(
      width = 10
      , uiOutput("plot.ui")
    )
  )
)
server <- function(input, output) {
  plotCount <- reactive({
    req(input$plotcount)
    as.numeric(input$plotcount)
  })
  plotHeight <- reactive(350 * plotCount())      
  output$plots <- renderPlot({
    req(plotCount())
    if (plotCount() == 0){
      plot.new()
      return()
    }
    opar <- par(mfrow = c(plotCount(), 1L))
    for (i in 1:plotCount()) {
      plot(1:100, 1:100, pch = 19)
    }
    par(opar)
  })
  output$plot.ui <- renderUI({
    plotOutput("plots", height = plotHeight())
  })
}
shinyApp(ui = ui, server = server)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With