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)