Problem getting height of renderPlot to be reactive to number of questions plotted

I'm trying to do something fairly simple -- change the height of a plot based on the number of questions plotted -- but I keep getting the message 'Operation not allowed without an active reactive context'. Anyone know what I am doing wrong?

A simplified example of the code I am using is shown below...

Will

server <- function(input, output) {

  
  plotheight <- reactive({
      length(qlist[topic==input$topic])
  })

 output$heatmap <- renderPlot(
     
   ggplot(plotdata(), aes(x=by, y=variable) + 
    geom_tile(aes(fill = Percent), colour = "white")),
      height=plotheight()*50
  )
	
}
2 Likes

What statement iscausing the error?

I guess it is just a typo, but you need to enclose the plotting code in curly braces, and your parenthesis are not matching properly:

 output$heatmap <- renderPlot({
     ggplot(plotdata(), aes(x=by, y=variable)) + 
       geom_tile(aes(fill = Percent), colour = "white")
  },
      height=plotheight()*50
  )

Thanks for that. I've made the change to the brackets, but it is still throwing the same error. The error code is saying that the plotOutput() is causing the error, but that's probably because it's calling the server function? Fuller code below...

Can you see what's the problem?

Define UI 
#==========
ui <- fluidPage(

	  fluidRow(
	  
	    column(10, titlePanel(img(src='logo.svg', style='width:300px;', align='left'), windowTitle = 'pupilinform')),
	    column(2, style = "margin-top: 50px;", actionButton('dlbutt', 'Download PDF'))
	    
	  ),
	
	  fluidRow(
	    
	    br(),
	    
	    column(3, selectInput('topic', 'Topic', choices = c('Exercise', 'Sleeping', 'Life skills', 'Missing school'))),
	    
	    column(3, selectInput('by', 'Plot by', choices = c('D1_01','YearGroup','SurveyYear'))),
	    
	    column(3, selectInput('main', 'Analysing', choices = c('Cheltenham','Gloucester','Forest of Dean'))),
	    
	    column(3, selectInput('comp', 'Comparator', choices = c('County')))
	           
	  ),
	  
	  plotOutput('heatmap')
	
)



# Define server logic 
#====================

server <- function(input, output) {

  plotdata <- reactive({
  by <- input$by 
  main <- input$main
  comp <- input$comp 
  idvars <- c('District', by) #add nearest neighbour here
  qvars <- qlist[groupQ=='yes' & qtype=='CHK' & topic==input$topic][['var']]
  vars <- c(idvars, qvars)
  
  a1 <- dat[, ..vars] #select the columns for this analysis
  a2 <- melt(a1, id.vars=idvars, measure.vars=qvars) #change to long format
  a3 <- a2[District==main,]
  a4 <- a3[, .N, keyby=.(by=get(by), variable, value)] #count up values by comparators
  a5 <- dcast(a4, by + variable ~ value, value.var='N', fun.aggregate = sum) #change to wide format
  a6 <- a5[, .(Y, N, Sum=sum(Y,N), Percent=Y/sum(Y, N)), keyby=.(by, variable)]#calculate percentages
  setnames(a6, old = 'by', new = paste0(by)) 
  a7 <- a6[, Facet:=main]
  
  c1 <- a2[grepl('*',District),] #wildcard for county
  c2 <- c1[, .N, keyby=.(by=get(by), variable, value)] #count up values by comparators
  c3 <- dcast(c2, by + variable ~ value, value.var='N', fun.aggregate = sum) #change to wide format
  c4 <- c3[, .(Y, N, Sum=sum(Y,N), Percent=Y/sum(Y, N)), keyby=.(by, variable)]#calculate percentages
  setnames(c4, old = 'by', new = paste0(by)) 
  c5 <- c4[, Facet:=comp]
  
  plotdat <- rbindlist(list(a7, c5), use.names = T)
  return(plotdat)
  })
  
  plotheight <- reactive({
    length(qlist[groupQ=='yes' & qtype=='CHK' & topic==input$topic][['var']])
  })
  
  
  output$heatmap <- renderPlot({
   ggplot(plotdata(), aes(x=by, y=variable) + geom_tile(aes(fill = Percent), colour = "white")     
    },
   
      height=plotheight()*50)
	
}


# Create Shiny object
#====================
shinyApp(ui = ui, server = server)

I think it might be that there is no value for plotheight() until a control is changed? How do I use a default value in output$heatmap unless somebody changes plotheight using the input$topic?

Will

I think it might have been to do with missing values in my dataset! Face palm
I'll check and might be back if not! Thanks for your help though, stkrog!

Will

Nope, still doesn't work :frowning:

It has to be inside a reactive function, like observer()

observe({
    output$heatmap <- renderPlot({
        ggplot(plotdata(), aes(x=by, y=variable) + 
                   geom_tile(aes(fill = Percent), colour = "white")),
        height=plotheight()*50
    })
})
2 Likes

Excellent! Thanks Andresrcs! That did it. I hadn't come across the observe functionality yet. Still learning! :slight_smile:

If your question's been answered (even by you!), would you mind choosing a solution? It helps other people see which questions still need help, or find solutions if they have similar problems. Here’s how to do it:

1 Like

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