Learning Objectives

Motivation

Basic Layouts

Title Panel

  • Add a title to your app using the titlePanel() function.

    library(shiny)
    
    ui <- fluidPage(
        titlePanel("My First Title")
    )
    
    server <- function(input, output) {
    
    }
    
    shinyApp(ui = ui, server = server)
  • Running the app, you should get something like this:

     

Grid Layout

  • To create a general layout, use the fluidRow() and column() functions.

  • fluidRow()

    • Creates a new row of panels.
    • Takes column() calls as input.
    • You place as many column() calls as you want columns.
    • It can have a title.
  • column()

    • Used as an argument in fluidRow().
    • The first argument should be a number between 1 and 12 (the width).
    • All column() calls should have widths that sum to 12.
    • The rest of the arguments are input/output elements to include in that column.
  • Hadley’s Graphic:

     

  • Let’s make a shiny app with two input columns in one row, and three plot columns in a second row.

    library(shiny)
    library(ggplot2)
    
    ui <- fluidPage(
      fluidRow(title = "Inputs",
               column(6,
                      selectInput("var1", "Variable 1", choices = names(mtcars)),
                      selectInput("var2", "Variable 2", choices = names(mtcars))
               ),
               column(6,
                      sliderInput("bins", "Number of Bins", min = 1, max = 50, value = 20)
               )
      ),
      fluidRow(title = "Outputs",
               column(4,
                      plotOutput("plot1")
               ),
               column(4,
                      plotOutput("plot2")
               ),
               column(4,
                      plotOutput("plot3")
               )
      )
    )
    
    server <- function(input, output) {
      output$plot1 <- renderPlot({
        ggplot(mtcars, aes(x = .data[[input$var1]], y = .data[[input$var2]])) +
          geom_point()
      })
    
      output$plot2 <- renderPlot({
        ggplot(mtcars, aes(x = .data[[input$var1]])) +
          geom_histogram(bins = input$bins)
      })
    
      output$plot3 <- renderPlot({
        ggplot(mtcars, aes(x = .data[[input$var2]])) +
          geom_histogram(bins = input$bins)
      })
    }
    
    shinyApp(ui = ui, server = server)
  • Running the app, you should get something like this:

     

  • Note: You can nest fluidRow()’s inside fluidRow()’s. It can get quite complicated.

  • Exercise: Create a grid layout of four squares where the top left square takes as input the variables of the palmerpenguins::penguins dataset to include in a scatterplot and the bottom right contains the resulting scatterplot, color-coded by species. The top right square and bottom left squares should remain empty.

    Your final app should look like this:

     

Tabsets

  • You can have outputs subdivided by tabs with tabsetPanel() and tabPanel().

  • tabsetPanel()

    • Takes as input tabPanel() calls.
    • You place it as an argument in either mainPanel() in the sidebar layout, or in one of the column() calls in the grid layout.
  • tabPanel()

    • Takes as input different input/output elements, separated by a comma. Each element will get its own tab.
    • Needs to be placed in tabsetPanel().
  • Here is an example from the mtcars dataset, where the tabs have different plots for the variables we select.

    library(shiny)
    library(ggplot2)
    
    ui <- fluidPage(
      sidebarLayout(
        sidebarPanel(
          selectInput("var1", "Variable 1", choices = names(mtcars)),
          selectInput("var2", "Variable 2", choices = names(mtcars)),
          sliderInput("bins", "Number of Bins", min = 1, max = 50, value = 20)
        ),
        mainPanel(
          tabsetPanel(
            tabPanel("Scatterplot",
                     plotOutput("plot1")
            ),
            tabPanel("Histogram of Variable 1",
                     plotOutput("plot2")
            ),
            tabPanel("Histogram of Variable 2",
                     plotOutput("plot3")
            )
          )
        )
      )
    )
    
    server <- function(input, output) {
      output$plot1 <- renderPlot({
        ggplot(mtcars, aes(x = .data[[input$var1]], y = .data[[input$var2]])) +
          geom_point()
      })
    
      output$plot2 <- renderPlot({
        ggplot(mtcars, aes(x = .data[[input$var1]])) +
          geom_histogram(bins = input$bins)
      })
    
      output$plot3 <- renderPlot({
        ggplot(mtcars, aes(x = .data[[input$var2]])) +
          geom_histogram(bins = input$bins)
      })
    }
    
    shinyApp(ui = ui, server = server)
  • Running the app, you should get something like this:

     

  • Exercise: Create a basic Shiny app that has a tab for a density plot, a histogram, and a boxplot for a variable from the palmerpenguins::penguins dataset. The user should get to choose the variable plotted, the the number of bins for the histogram, and the bandwidth for the density plot (see the help page of geom_smooth()). A good default value for the bandwidth might be 0.25 in this case.

    Your app should look like this:

     

Group Elements Together

Other Panels

Shiny Themes

Shiny Dashboards