Search code examples
rshinyplotlyrenderingshiny-reactivity

Is it possible to have a dynamic chart type in shiny? (Type of output changes based on input)


I want the chart to appear in the same location in the UI but the type of chart output depends on what the user selects. The example doesn't work but might explain what I'm looking for.

Simple Example

library(shiny)

# Define UI 
ui <- fluidPage(

    # Application title
    titlePanel("Title"),

    # Sidebar 
    sidebarLayout(
        sidebarPanel(
            selectInput("time", "Select time frame", choices = c("Hour", "Minute", "Day", "Month"), selected = "Day")
        ),

        # Show a plot of the generated distribution
        mainPanel(
           uiOutput("plot")
        )
    )
)

# Define server 
server <- function(input, output) {
    output$plot = renderUI({
        if(input$time %in% c("Hour", "Minute")){
            renderPlot(mtcars %>% ggplot(aes(disp, mpg )) + geom_point())
        }
        else if(input$time %in% c("Day", "Month")){
            renderPlotly(mtcars %>% ggplot(aes(disp, mpg )) + geom_point())
        }
    })
   
}

# Run the application 
shinyApp(ui = ui, server = server)

Please let me know if something like this is possible


Solution

  • I think this could suffice. You can have the renderUI conditionally switch a plotOutput so it shows in the same area. Using the bulk of your code, I changed the if statements to have a plot/plotly output instead of the render plot/plotly. Then I have a separate render plot/plotly output for each of these new plots, which I labeled plot1/2

    library(shiny)
    library(ggplot2)
    library(plotly)
    
    # Define UI 
    ui <- fluidPage(
      
      # Application title
      titlePanel("Title"),
      
      # Sidebar 
      sidebarLayout(
        sidebarPanel(
          selectInput("time", "Select time frame", choices = c("Hour", "Minute", "Day", "Month"), selected = "Day")
        ),
        
        # Show a plot of the generated distribution
        mainPanel(
          uiOutput("plot")
        )
      )
    )
    
    # Define server 
    server <- function(input, output) {
      
      output$plot = renderUI({
        if(input$time %in% c("Hour", "Minute")){
            plotOutput("plot1")
        } else if(input$time %in% c("Day", "Month")){
            plotlyOutput("plot2")
        }
      })
      
      output$plot1<-renderPlot({
        mtcars %>% ggplot(aes(disp, mpg )) + geom_point()
      })
      
      output$plot2<-renderPlotly({
        mtcars %>% ggplot(aes(disp, mpg )) + geom_point()
      })
      
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    

    I hope this works! Best of luck!