Layout Practical

R
Shiny
App Design

Learn how to enhance the visual structure and usability of your Shiny applications by organizing the user interface with sidebarPanel(), mainPanel(), and tabsetPanel(). In this hands-on practical, you will redesign an existing interactive data visualization app (using mtcars) to separate controls, plots, and tables into logical, easy-to-navigate sections. This activity will help you develop key design skills for building more effective R Shiny dashboards.

Authors

Will Gammerdinger

Meeta Mistry

Published

November 12, 2025

Keywords

Layout, User interface, sidebarPanel, tabsetPanel

Layout Practical

Let’s enhance the layout of the app that we created in the practical exercise last session:

library(shiny)
library(DT)
library(tidyverse)

# User Interface
ui <- fluidPage(
  # Dropdown menu to select which column will be used for the x-axis
  selectInput(inputId = "x_axis_input",
              label = "Select x-axis",
              choices = colnames(mtcars),
              selected = "mpg"), 
   # Dropdown menu to select which column will be used for the y-axis
  selectInput(inputId = "y_axis_input",
              label = "Select y-axis",
              choices = colnames(mtcars),
              selected = "disp"),
  # The output plot
  plotOutput(outputId = "plot",
             brush = "plot_brush"),
  # The output table
  DTOutput("table")
)

# Server
server <- function(input, output) {
  # Render the scatter plot
  output$plot <- renderPlot({
    # Scatter plot creation
    ggplot(mtcars) +
      geom_point(aes_string(x = input$x_axis_input,
                            y = input$y_axis_input))
  })
  # Render a table from points within the rectangle created by clicking and dragging over the plot
  output$table <- renderDT({
    brushedPoints(mtcars, input$plot_brush)
  })
}

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

Let’s place the selectInput() in a sidebarPanel() and then in the mainPanel(), let’s use a tabset where the plot is in one tab and the brushed table is in another tab. The app should look like this:


Back to Schedule

Reuse

CC-BY-4.0