Render plots that are generated using a loop with a custom function in different tabs

I am a beginner to shiny and shinydashboard. Currently, I would like to have 2 different tabs that are able to generate multiple plots if the appropriate CSV file(s) are inserted.

I have functions to format users CSV files which turn them into data frames that are contained in a list. I then have another function that can plot these data frames (turn them into copy number plot). This is the simplified version of what I currently have for the dashboard...

ui <-
  dashboardPage(
    skin = "blue",
    dashboardHeader(title = "Dashboard"),
    dashboardSidebar(
      sidebarMenu(
        menuItem("Guide", tabName = "Guide", icon = icon("info")),
        menuItem("Copy-Number-Analysis", icon = icon("dna"),
                 menuSubItem("Filtered-Amplicon", tabName = "Filtered-Amplicon", icon = icon("arrow-alt-circle-right")),
                 menuSubItem("Whole-Chromosome", tabName = "Whole-Chromosome", icon = icon("arrow-alt-circle-right"))
                 )
      )
    ),
    dashboardBody(
      tabItems(
        tabItem(tabName = "Guide",
                fluidRow(box(
                  title = strong("How do I use this application?",style = "font-size: 160%;"),
                ))
        ),
        tabItem(tabName = "Filtered-Amplicon",
                fluidRow(box(
                  title = strong("Filtered Amplicon Copy Number Plot", style = "font-size: 160%;"),
                  status = "danger",
                  solidHeader = T,
                  width = 12,
                  fileInput("file1", h4("Input your file(s) in csv format!"),
                            accept = c(
                              "text/csv",
                              "text/comma-separated-values,text/plain",
                              ".csv"),
                            multiple = TRUE
                  ),
                  uiOutput("PlotVisualizeAmplicon") #Visualize plot
                ))),
        tabItem(tabName = "Whole-Chromosome",
                fluidRow(box(
                  title = strong("Whole Chromosome Copy Number Plot", style = "font-size: 160%;"),
                  status = "danger",
                  solidHeader = T,
                  width = 12,
                  fileInput("file2", h4("Input your file(s) in csv format!"),
                            accept = c(
                              "text/csv",
                              "text/comma-separated-values,text/plain",
                              ".csv"),
                            multiple = TRUE
                  ),
                  uiOutput("PlotVisualizeWhole") #Visualize plot
                ))
                )
        )
      )
    )
  )

server <- function(input, output) {
  #Set the number of max input
  maxPlot <- 100

  #AMPLICON PLOT
  #Data Input
  dataPlotInput2 <- reactive({
    if(is.null(input$file1)){return()}

    #Input CSVs
    files_name <- as.list(rep(NA, length(input$file1$datapath)))
    for (i in 1:length(input$file1$datapath)){
      files_name[[i]] <- as.character(input$file1[i,4])
    }

    files_list <- as.list(rep(NA, length(input$file1$datapath)))
    for(i in 1:length(input$file1$datapath)){
      files_list[[i]] <-  read_csv(
        file = as.character(files_name[[i]]))%>%
        select(1:5)
    }
    names(files_list) <- files_name

    #Copy Number analysis
    files_formated <- format_all(files_list)
    comparison_tbl_Amplicon <- ref_compare_all(files_formated, reference = reference1)
    comparison_tbl_Amplicon
  })
  # Produce plot(s)
  for (i in 1:maxPlot) {
    local({
      my_i <- i
      plotnameAmplicon <- paste("plot", my_i, sep="")
      output[[plotnameAmplicon]] <- renderPlot({
        plot_aneuploid(dataPlotInput2()[[my_i]], size = 2) + ggtitle(as.character(input$file1[my_i,1]))
      })
    })
  }
  output$PlotVisualizeAmplicon <- renderUI({
    if(is.null(input$file1)){return()}

    FileNumber <- nrow(input$file1)

    plot_output_list_Amplicon <- lapply(1:FileNumber, function(i) {
      plotnameAmplicon <- paste("plot", i, sep="")
      plotOutput(plotnameAmplicon, width = "100%", height = "400px")
    })
    do.call(tagList, plot_output_list_Amplicon)
  })

  ##WHOLE CHROMOSOME PLOT
  #Data input
  dataPlotInput3 <- reactive({
    if(is.null(input$file2)){return()}

    #Input CSVs
    files_name <- as.list(rep(NA, length(input$file2$datapath)))
    for (i in 1:length(input$file2$datapath)){
      files_name[[i]] <- as.character(input$file2[i,4])
    }

    files_list <- as.list(rep(NA, length(input$file2$datapath)))
    for(i in 1:length(input$file2$datapath)){
      files_list[[i]] <-  read_csv(
        file = as.character(files_name[[i]]))%>%
        select(1:5)
    }
    names(files_list) <- files_name

    #Copy Number analysis
    files_formated <- format_all(files_list)
    comparison_tbl_Whole <- ref_compare_whole_chr_all(files_formated, reference = reference1)
    comparison_tbl_Whole
  })
  #Produce plot(s)
  for (i in 1:maxPlot) {
    local({
      my_j <- i
      plotnameWhole <- paste("plot", my_j, sep="")

      output[[plotnameWhole]] <- renderPlot({
        plot_aneuploid_whole_chr(dataPlotInput3()[[my_j]], size = 2) + ggtitle(as.character(input$file2[my_j,1]))
      })
    })
  }
  output$PlotVisualizeWhole <- renderUI({
    if(is.null(input$file2)){return()}

    FileNumber <- nrow(input$file2)

    plot_output_list_Whole <- lapply(1:FileNumber, function(i) {
      plotnameWhole <- paste("plot", i, sep="")
      plotOutput(plotnameWhole, width = "100%", height = "400px")
    })
    do.call(tagList, plot_output_list_Whole)
  })


}

My final goal is to able to produce different plots in the two tabs that I have which should look something like this with me being able to use them alternately...

I am currently unable to simultaneously generate both plots in different tabs. I am only able to generate them only if the other tab does not exist (I turn the unused tabs into comments to generate these images).

The way I visualize the plot is by having uiOutput in the ui function. I generated my plots inside output[[plotnameAmplicon]] and output[[plotnameWhole]] with renderPlot. I then use renderUi to show all the plots. This method works only when the other plotting tab does not exist. If I ran the code that I currently have, for some reason the results of tab2 appear in tab1 and I cannot generate tab 1 plots. Is there a way to fix this. Any suggestion to improve the plotting logic is also highly appreciated as I am new to shiny and shinydashboard.

I have found the solution. By encapsulating renderPlot inside renderUi and by giving different variable name for renderPlot (silly mistake by me), I was able to produce the desired output.

  output$PlotVisualizeWhole <- renderUI({
    if(is.null(input$file2)){return()}

    FileNumber <- nrow(input$file2)

    plot_output_list_Whole <- lapply(1:FileNumber, function(i) {
      plotnameWhole <- paste("plotwhole", i, sep="")
      output[[plotnameWhole]] <- renderPlot({
        plot_aneuploid_whole_chr(dataPlotInput3()[[i]], size = 2) + ggtitle(as.character(input$file2[i,1]))})
      plotDownload <- paste("Downloaded", i, sep = "")
      plotOutput(plotnameWhole, width = "100%", height = "400px")
    })
    do.call(tagList, plot_output_list_Whole)
  })

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