Theming
shinythemes
There are many other ways of customizing the look of your app, including using custom CSS. However one quick and easy way of changing the look is using the prebuilt themes in the shinythemes
package.
In order to use one of these themes, you need to load the shinythemes
package first. The package website has thumbnail images of each of the themes, but it can be difficult to tell exactly how the theme will look on your app.
themeSelector()
A useful tool for browsing themes is the themeSelector()
widget. To use this widget, simply add the widget to your app.
It can be inserted anywhere inside of the application, although if it is put inside a tab, it will be visible only when that tab is showing. I usually place it right underneath the fluidPage()
definition.
This widget is to be used in development only. Once you decide on a theme, you should remove the widget and just define the theme you want using the shinytheme()
function.
fluidPage(
::themeSelector(),
shinythemes
... )
Other theming options
The bslib package provides tools for customizing Bootstrap themes directly from R, making it much easier to customize the appearance of Shiny apps & R Markdown documents.
The thematic package provides a functionality for simplified theming of ggplot2, lattice, and {base} R graphics as well as automatic theming of these plots within a Shiny app.
Next up you get to build an app with tabs and see how it looks with different shiny themes.
Practice - Theming
Your turn
- Pick a theme and apply to the existing app. See https://rstudio.github.io/shinythemes for more on theme options.
Complete the exercise by navigating to the Posit Cloud Project titled 4-4 Customize the appearance of your app with shinythemes in your Posit Cloud Workspace
# Load packages ----------------------------------------------------------------
library(shiny)
library(ggplot2)
library(tools)
library(shinythemes)
# Load data --------------------------------------------------------------------
load("movies.RData")
# Define UI --------------------------------------------------------------------
<- fluidPage(
ui sidebarLayout(
sidebarPanel(
selectInput(
inputId = "y",
label = "Y-axis:",
choices = c(
"IMDB rating" = "imdb_rating",
"IMDB number of votes" = "imdb_num_votes",
"Critics Score" = "critics_score",
"Audience Score" = "audience_score",
"Runtime" = "runtime"
),selected = "audience_score"
),
selectInput(
inputId = "x",
label = "X-axis:",
choices = c(
"IMDB rating" = "imdb_rating",
"IMDB number of votes" = "imdb_num_votes",
"Critics Score" = "critics_score",
"Audience Score" = "audience_score",
"Runtime" = "runtime"
),selected = "critics_score"
),
selectInput(
inputId = "z",
label = "Color by:",
choices = c(
"Title Type" = "title_type",
"Genre" = "genre",
"MPAA Rating" = "mpaa_rating",
"Critics Rating" = "critics_rating",
"Audience Rating" = "audience_rating"
),selected = "mpaa_rating"
),
sliderInput(
inputId = "alpha",
label = "Alpha:",
min = 0, max = 1,
value = 0.5
),
sliderInput(
inputId = "size",
label = "Size:",
min = 0, max = 5,
value = 2
),
textInput(
inputId = "plot_title",
label = "Plot title",
placeholder = "Enter text to be used as plot title"
),
actionButton(
inputId = "update_plot_title",
label = "Update plot title"
)
),
mainPanel(
$br(),
tags$p(
tags"These data were obtained from",
$a("IMBD", href = "http://www.imbd.com/"), "and",
tags$a("Rotten Tomatoes", href = "https://www.rottentomatoes.com/"), "."
tags
),$p("The data represent", nrow(movies), "randomly sampled movies released between 1972 to 2014 in the United States."),
tags
plotOutput(outputId = "scatterplot")
)
)
)
# Define server ----------------------------------------------------------------
<- function(input, output, session) {
server <- eventReactive(
new_plot_title eventExpr = input$update_plot_title,
valueExpr = {
toTitleCase(input$plot_title)
}
)
$scatterplot <- renderPlot({
outputggplot(data = movies, aes_string(x = input$x, y = input$y, color = input$z)) +
geom_point(alpha = input$alpha, size = input$size) +
labs(title = new_plot_title())
})
}
# Create the Shiny app object --------------------------------------------------
shinyApp(ui = ui, server = server)
# Load packages ----------------------------------------------------------------
library(shiny)
library(ggplot2)
library(tools)
library(shinythemes)
# Load data --------------------------------------------------------------------
load("movies.RData")
# Define UI --------------------------------------------------------------------
<- fluidPage(theme = shinytheme("united"),
ui sidebarLayout(
sidebarPanel(
selectInput(
inputId = "y",
label = "Y-axis:",
choices = c(
"IMDB rating" = "imdb_rating",
"IMDB number of votes" = "imdb_num_votes",
"Critics Score" = "critics_score",
"Audience Score" = "audience_score",
"Runtime" = "runtime"
),selected = "audience_score"
),
selectInput(
inputId = "x",
label = "X-axis:",
choices = c(
"IMDB rating" = "imdb_rating",
"IMDB number of votes" = "imdb_num_votes",
"Critics Score" = "critics_score",
"Audience Score" = "audience_score",
"Runtime" = "runtime"
),selected = "critics_score"
),
selectInput(
inputId = "z",
label = "Color by:",
choices = c(
"Title Type" = "title_type",
"Genre" = "genre",
"MPAA Rating" = "mpaa_rating",
"Critics Rating" = "critics_rating",
"Audience Rating" = "audience_rating"
),selected = "mpaa_rating"
),
sliderInput(
inputId = "alpha",
label = "Alpha:",
min = 0, max = 1,
value = 0.5
),
sliderInput(
inputId = "size",
label = "Size:",
min = 0, max = 5,
value = 2
),
textInput(
inputId = "plot_title",
label = "Plot title",
placeholder = "Enter text to be used as plot title"
),
actionButton(
inputId = "update_plot_title",
label = "Update plot title"
)
),
mainPanel(
$br(),
tags$p(
tags"These data were obtained from",
$a("IMBD", href = "http://www.imbd.com/"), "and",
tags$a("Rotten Tomatoes", href = "https://www.rottentomatoes.com/"), "."
tags
),$p("The data represent", nrow(movies), "randomly sampled movies released between 1972 to 2014 in the United States."),
tags
plotOutput(outputId = "scatterplot")
)
)
)
# Define server ----------------------------------------------------------------
<- function(input, output, session) {
server <- eventReactive(
new_plot_title eventExpr = input$update_plot_title,
valueExpr = {
toTitleCase(input$plot_title)
}
)
$scatterplot <- renderPlot({
outputggplot(data = movies, aes_string(x = input$x, y = input$y, color = input$z)) +
geom_point(alpha = input$alpha, size = input$size) +
labs(title = new_plot_title())
})
}
# Create the Shiny app object --------------------------------------------------
shinyApp(ui = ui, server = server)