0
votes

I'm trying to create the scenario whereby using conditionalpanel, I am able to have an user input of checked boxes to display either 1 or 2 plots, one after another.

My reproducible code can be found below, however, I am unable to display the plots.

Could someone please share with me where did I make a mistake?

library(shiny)

ui = fluidPage(
  titlePanel("Plot1 or Plot2?"),
  sidebarLayout(
    sidebarPanel(
      checkboxGroupInput("my_choices", "Plot1 or Plot2",choices = c("Plot1", "Plot2"), selected = "Plot1"),width=2),
    mainPanel(
      conditionalPanel(
        condition = "input.my_choices == 'Plot1'",
        plotOutput("plot1")
      ),
      conditionalPanel(
        condition = "input.my_choices == 'Plot2'",
        plotOutput("plot2")
      ), 
      conditionalPanel(
        condition = "input.my_choices.includes('Plot1', 'Plot2')",
        plotOutput("plot1"),
        plotOutput("plot2")
      )
    )
  )
)

server = function(input, output) {

  output$plot1 <- renderPlot({plot(iris)})
  output$plot2 <- renderPlot({plot(mtcars)})
}

shinyApp(ui, server)

Update:

I've got what I wanted but without using ConditionalPanel function. Here's the code below:

Would appreciate if someone can share with me the proper way of using ConditionalPanel Function! (:

library(shiny)

#data
df <- iris

#ui
ui <- fluidPage(
    sidebarPanel(
      checkboxGroupInput(inputId = "Question",
                         label = "Choose the plots",
                         choices = c("Plot1", "Plot2", "Plot3"),
                         selected = "")),
    mainPanel(
      uiOutput('ui_plot') 
    )
  )

#server
server <- function(input, output)
{
  # gen plot containers
  output$ui_plot <- renderUI({ 
    out <- list()
    if (length(input$Question)==0){return(NULL)}
    for (i in 1:length(input$Question)){
      out[[i]] <-  plotOutput(outputId = paste0("plot",i))
    }  
    return(out) 
  })

  # render plots
  observe({  
    for (i in 1:3){  
      local({  #because expressions are evaluated at app init
        ii <- i 
        output[[paste0('plot',ii)]] <- renderPlot({ 
          if ( length(input$Question) > ii-1 ){  
            return(plot(runif(100)))
          } 
          NULL
        })
      })
    }                                  

  })

}

shinyApp(ui, server)
1

1 Answers

4
votes

I would give you an alternative as you will need to create new plots with different id in order for that to work. The simplest one I can think of is using shinyjs package and its hide and show functions. You can also do this via renderUI but you shouldn't give unnecessary work to your server only if you're showing and hiding the elements

library(shiny)
library(shinyjs)

ui = fluidPage(
  useShinyjs(),
  titlePanel("Plot1 or Plot2?"),
  sidebarLayout(
    sidebarPanel(
      checkboxGroupInput("my_choices", "Plot1 or Plot2",choices = c("Plot1", "Plot2"), selected = "Plot1"),width=2),
    mainPanel(
      plotOutput("plot1"),
      plotOutput("plot2")
    )
  )
)

server = function(input, output,session) {

  # hide plots on start
  hide("plot1");hide("plot2")

  output$plot1 <- renderPlot({plot(iris)})
  output$plot2 <- renderPlot({plot(mtcars)})

  observeEvent(input$my_choices,{

    if(is.null(input$my_choices)){
      hide("plot1"); hide("plot2")
    }

    else if(length(input$my_choices) == 1){
      if(input$my_choices == "Plot1"){
        show("plot1");hide("plot2")
      }
      if(input$my_choices == "Plot2"){
        hide("plot1");show("plot2")
      }
    }

    else{

      if(all(c("Plot1","Plot2") %in% input$my_choices)){
        show("plot1");show("plot2")
      }
    }
  },ignoreNULL = F)
}

shinyApp(ui, server)

enter image description here