0

I'm trying to populate dynamically generated tabs with plots made from a loop but can't get the tabs to populate with all of the plots generated in the loop.

shinyUI(pageWithSidebar(

  headerPanel("Dynamic number of plots"),

sidebarPanel(
),

mainPanel(
# This is the dynamic UI for the plots
uiOutput("IndividualPlots")
 )
))

server <- function(input, output) {

output$IndividualPlots <- renderUI({
  if (is.null(input$data_cqt0)) {
    return()
  }
  plot_content()
  shiny:::buildTabset(
    id = "t",
    lapply(1:PageNumber(), function(i){
      plotname <- paste("plot", i, sep="")
      tabPanel(title = sprintf("Page_%s",i),
               #browser(),
               plotOutput(plotname,width = "800px", height = "600px") 
      )
    }), 
    paste0("nav nav-","tabs")) %>% (function(x){
      tags$div(class = "tabbable", x[[1]], x[[2]])
    })
})


plot_content<- reactive({
  for (i in 1:PageNumber()) {
    local({
      my_i <- i
      plotname <- paste("plot", my_i, sep="")   
      output[[plotname]] <- renderPlot({
          print(Plots()[[i]])
      })
    })
  }
})

PageNumber <- reactive({
  data <- data()
  return(PlotPageNumber(data, input$Class)) ## Returns number of plots
})



Plots <- reactive({
    data <- data()
     return(PlotFunction(data, input$Class)) ## Returns plots in list
    })
   }

This code almost works but it populates both tabs with the last plot in the plot_content() index. I'm stuck as to how to get all the plots from plot_content() to dynamically fill the appropriate number of tabs created.

1 Answers1

1

Your problem is that Shiny reactives evaluate lazily. As a result, when the plots render, the value of the index, i, is equal to PageNumber() for all of them. My preferred solution to this problem is to create a module to manage the display the plots. (The module can also handle any other plot-related activity as well.) A different instance of the module manages each individual plot. The result is code which is usually shorter, more robust, and easier to understand and maintain than other solutions.

Although the OP's main question is different to yours, my answer (specifically the second revision) to this post is a demonstration of this technique.

Limey
  • 10,234
  • 2
  • 12
  • 32