Home > Enterprise >  Display the output of several plots on top of each other in Shiny App
Display the output of several plots on top of each other in Shiny App

Time:07-20

I am making a Shiny App that generates a graph and in the application there is the option to modify this graph. In the mainPanel() I have 6 plotOutputs and I would like that each time that one of these 6 modifications is made the graph comes out the first one (above the previous one). Currently I get them in order as they are in mainPanel and at the top if I draw "tree" and "rotate" it leaves a space between the graphics as if "reroot" was missing. Photo as it appears now

For example, the first graph to be generated is "tree". If I make the modification "rotate", the graph should come out just above the other one (without leaving spaces). And if I then do "flip", this graph would come out on top of "rotate".

Is there any possibility to do it? Would it also be possible to show only 3 plots? That is to say, if there are already 3 graphs in the panel and I want to make a fourth modification, the graph that has been generated first (the last of the panel) will not be drawn.

ui <- fluidPage(
  
  # Sidebar layout with input and output definitions
  sidebarLayout(
    
    # Sidebar panel for inputs
    sidebarPanel(
      
      span(titlePanel("Shiny App"), style = "text-align: center"),
      
      p(span("Shiny application to facilitate the construction, editing and manipulation of phylogenetic trees."), style = "font-size: 16px; color: #00509D"), #9B9D9F
      br(), 
      
      radioButtons(inputId = "start",
                   label = "Select an option:", 
                   choices = c("Choose file .tre" = "file", 
                               "Search in PR2 database" = "PR2"),
                   selected = "Choose file .tre"), #FUNCIONA: selected = "file"
      
      conditionalPanel(
        condition = "input.start == 'file'",
        fileInput(inputId = "tre",
                  label = "Choose file:")
        ),
    
      conditionalPanel(
        condition = "input.start == 'PR2'",
        selectInput(inputId = "tax",
                    label = "Choose taxonomic group:",
                    choices = c("Domain", "Kingdom", "Phylum", "Class", "Order", "Family", "Genus", "Species"),
                    selected = "Order"),
        textInput(inputId = "clade",
                  label = "Group name:",
                  value = "Suessiales"),
        # Help
        helpText("You can run the example to build a phylogenetic tree 
               for the order Suessiales, unicellular organisms of the 
               superclass Dinoflagellata.")
      ),
      
      p("_____________________________"),
      checkboxInput(inputId = "root",
                    label = strong("Reroot")),
      
      numericInput(inputId = "val_root",
                   label = "Branch number:",
                   value = 87),
      
      checkboxInput(inputId = "rot",
                    label = strong("Rotate")),
      
      numericInput(inputId = "val_rot",
                   label = "Branch number:",
                   value = 87),
      
      checkboxInput(inputId = "flip",
                    label = strong("Flip")),
      
      numericInput(inputId = "val_f1",
                   label = "Node 1 number:",
                   value = 87),
      
      numericInput(inputId = "val_f2",
                   label = "Node 2 number:",
                   value = 72),
      
      p("_____________________________"),
      checkboxInput(inputId = "rename",
                    label = strong("Rename branches")),
      fileInput(inputId = "refile",
                label = "Choose file:")
      
    ),
    
    # Main panel for displaying outputs ----
    mainPanel(
      
      plotOutput("tree"),
      
      plotOutput("root"),

      plotOutput("rotate"),

      plotOutput("flip"),
      
      plotOutput("rename")
      
    )
  )
)

CodePudding user response:

This is possible when you let the server render the order of the charts.

The solution uses a reactive expression ChartOrder where it places the order of the charts. For every chart an observer handles the dependency to the input widgets and re-orders ChartOrder.

The output$ListOfCharts renders the order accordingly.

UsingChartOrder you can change the order or filter out a chart (see input$showPlot3).

library(shiny)

ui <- fluidPage(
  # App title ----
  titlePanel("Hello Shiny!"),

  # Sidebar layout with input and output definitions ----
  sidebarLayout(

    # Sidebar panel for inputs ----
    sidebarPanel(

      # Input: Slider for the number of bins ----
      sliderInput(inputId = "bins",
                  label = "Number of 'Waiting' bins:",
                  min = 1,
                  max = 50,
                  value = 30),

      sliderInput(inputId = "binsErupt",
                  label = "Number of 'Eruption' bins:",
                  min = 1,
                  max = 25,
                  value = 2),

      checkboxInput(inputId = "showPlot3", "Show third plot")
    ),

    # Main panel for displaying outputs ----
    mainPanel(
      uiOutput("ListOfCharts")
    )
  )
)

server <- function(input, output, session) {
  PutChartOnTop <- function(This, ChartList) {
    c(This, ChartList[ChartList != This])
  }

  ChartOrder <- reactiveVal(list("distPlot1", "timePlot2", "Plot3"))

  output$ListOfCharts <- renderUI({
    Order <- ChartOrder()

    ui <- lapply(Order, plotOutput)
    class(ui) <- c("shiny.tag.list", "list")
    return(ui)
  })

  observeEvent(
    input$bins,
    ChartOrder(PutChartOnTop("distPlot1", ChartOrder())))

  observeEvent(
    input$binsErupt,
    ChartOrder(PutChartOnTop("timePlot2", ChartOrder())))

  observeEvent(
    input$showPlot3,
    {
      if (input$showPlot3) {
        ChartOrder(PutChartOnTop("Plot3", ChartOrder())) # add plot on top
      } else {
        ChartOrder(ChartOrder()[ChartOrder() != "Plot3"]) # filter out plot 3
      }
    })

  output$distPlot1 <- renderPlot({
    x    <- faithful$waiting
    bins <- seq(min(x), max(x), length.out = input$bins   1)

    hist(x, breaks = bins, col = "#75AADB", border = "white",
         xlab = "Waiting time to next eruption (in mins)",
         main = "Histogram of waiting times")
  })



  output$timePlot2 <- renderPlot({
    x    <- faithful$eruptions
    bins <- seq(min(x), max(x), length.out = input$binsErupt   1)

    hist(x, breaks = bins, col = "#AADB75", border = "white",
         xlab = "Eruption time in mins",
         main = "Histogram of eruption duration")

  })



  output$Plot3 <- renderPlot({
    x <- faithful$waiting
    y <- faithful$eruptions

    plot(x, y, col = "#DB75AA", border = "white",
         xlab = "Waiting Time",
         main = "Waiting Times X Eruption Duration")

  })
}

shinyApp(ui, server)

  • Related