NDPalette carries the same Notre Dame colors through
every layer of an interactive report, so a Shiny app’s page chrome, its
prose, and its figures all read as one brand palette. This vignette
builds a small, complete app, explains the three pieces that do the
theming, and closes with a showcase of every color the package provides,
with notes on what each is for. It is an independent project, not
affiliated with or endorsed by the University.
A Shiny app themed with NDPalette rests on three
pieces:
bslib theme whose Bootstrap colors
are pulled from the palette with nd_color(), so buttons,
links, and headers are brand-colored;scale_*_nd() scales, so every
figure is painted from the same palette; andnd_tints
or nd_informal_tints.The app below is shipped with the package. Run it with:
Its full source (inst/examples/nd-shiny-app/app.R),
shown straight from the installed file so it never drifts from what
actually runs:
# A Shiny palette explorer themed with NDPalette.
#
# It colors the page chrome from the Notre Dame palette with a bslib theme,
# lets you switch among three page backgrounds (plain white, the informal
# soft white, and the informal soft yellow), paints the figure with the
# scale_*_nd() scales, and shows the exact theme code with a copy button and
# a show/hide toggle. A download button saves the current palette as a CSV.
#
# Run it with:
# shiny::runApp(system.file("examples", "nd-shiny-app", package = "NDPalette"))
library(shiny)
library(ggplot2)
library(NDPalette)
# Three page backgrounds to choose from: plain white, and two soft
# informal tints (which are NOT Notre Dame brand colors -- non-white
# alternatives to a plain white page).
bg_choices <- c(
"White" = "#ffffff",
"Soft white" = unname(nd_informal_tints[["soft_white"]]),
"Soft yellow" = unname(nd_informal_tints[["soft_yellow_light"]])
)
# A bslib theme with the chosen background; text and accents stay brand
# colors, so only the page background changes between choices.
nd_theme <- function(bg) {
bslib::bs_theme(
version = 5,
bg = bg,
fg = nd_color("navy"),
primary = nd_color("navy"),
secondary = nd_color("bright_gold")
)
}
# The theme code as text, for the copy-the-code panel.
theme_code <- function(bg_name, bg) {
paste(
"bslib::bs_theme(",
" version = 5,",
sprintf(' bg = "%s", # %s', bg, bg_name),
' fg = nd_color("navy"),',
' primary = nd_color("navy"),',
' secondary = nd_color("bright_gold")',
")",
sep = "\n"
)
}
ui <- bslib::page_sidebar(
theme = nd_theme(bg_choices[["Soft white"]]),
title = "NDPalette — a Notre Dame palette explorer",
sidebar = bslib::sidebar(
radioButtons("bg", "Page background", names(bg_choices),
selected = "Soft white"),
selectInput("palette", "Palette",
c("Notre Dame (nd)" = "nd",
"Colorblind-friendly (nd_cvd)" = "nd_cvd",
"Former colors (former)" = "former")),
sliderInput("n", "Number of groups", min = 2, max = 10, value = 5),
checkboxInput("reverse", "Reverse color order", FALSE),
checkboxInput("show_code", "Show theme code", FALSE), # the hide option
downloadButton("dl", "Download palette (CSV)", class = "btn-sm")
),
bslib::card(
bslib::card_header("Swatches"),
plotOutput("swatch", height = "110px")
),
# The theme code, shown only when "Show theme code" is checked, with a
# button that copies it to the clipboard.
conditionalPanel(
condition = "input.show_code",
bslib::card(
bslib::card_header(
"Theme code",
tags$button(
"Copy", class = "btn btn-sm btn-primary float-end",
onclick = paste0(
"navigator.clipboard.writeText(",
"document.getElementById('themecode').innerText)")
)
),
verbatimTextOutput("themecode")
)
),
bslib::card(
bslib::card_header("A grouped figure painted with scale_color_nd()"),
plotOutput("plot", height = "340px")
),
bslib::card(
bslib::card_header("Color reference (nd_colors)"),
tableOutput("table")
)
)
server <- function(input, output, session) {
# Switch the live theme when the background choice changes.
observeEvent(input$bg, {
session$setCurrentTheme(nd_theme(bg_choices[[input$bg]]))
})
cols <- reactive(
nd_palette(input$n, palette = input$palette, reverse = input$reverse)
)
output$swatch <- renderPlot(show_palette(cols()))
output$plot <- renderPlot({
set.seed(113)
groups <- factor(LETTERS[seq_len(input$n)])
df <- data.frame(x = rnorm(input$n * 40), y = rnorm(input$n * 40),
group = rep(groups, each = 40))
ggplot(df, aes(x, y, color = group)) +
geom_point(size = 2, alpha = 0.85) +
scale_color_nd(palette = input$palette, reverse = input$reverse) +
theme_minimal(base_size = 13) +
labs(x = NULL, y = NULL, color = NULL)
})
output$themecode <- renderText(theme_code(input$bg, bg_choices[[input$bg]]))
output$table <- renderTable(
nd_colors[, c("name", "key", "hex", "role", "description")]
)
output$dl <- downloadHandler(
filename = function() sprintf("nd_palette_%s_%d.csv", input$palette, input$n),
content = function(file) {
utils::write.csv(data.frame(position = seq_along(cols()), hex = cols()),
file, row.names = FALSE)
}
)
}
shinyApp(ui, server)
Beyond the theming, the app lets you switch among three page
backgrounds (plain white, the informal soft white, and the
informal soft yellow) live with session$setCurrentTheme(),
shows the exact bs_theme() code in a panel
you can show or hide with a checkbox, with a Copy
button that puts it on the clipboard, and a Download palette
(CSV) button. Three small pieces do that work:
# 1. The three backgrounds (white, plus two soft informal tints):
bg_choices <- c("White" = "#ffffff",
"Soft white" = nd_informal_tints[["soft_white"]],
"Soft yellow" = nd_informal_tints[["soft_yellow_light"]])
# 2. Re-theme live when the choice changes:
observeEvent(input$bg, session$setCurrentTheme(nd_theme(bg_choices[[input$bg]])))
# 3. A copy-to-clipboard button for the shown code (plain HTML + JS):
tags$button("Copy", class = "btn btn-sm btn-primary",
onclick = "navigator.clipboard.writeText(
document.getElementById('themecode').innerText)")The three page backgrounds, side by side — plain white and two soft
informal tints, all carrying navy text. (For an even lighter touch, the
faint_white and faint_yellow tints sit just
off pure white.)
bslib themebslib::bs_theme() accepts colors for the Bootstrap
roles. Pulling them from nd_color() ties the page chrome to
the palette: navy foreground and primary, bright gold secondary, on a
soft background.
nd_theme <- bslib::bs_theme(
version = 5,
bg = nd_informal_tints[["soft_yellow"]], # soft, non-white page
fg = nd_color("navy"),
primary = nd_color("navy"),
secondary = nd_color("bright_gold")
)For a more reserved page, use one of the official Warm Whites instead
of the informal soft yellow, for example
bg = nd_tints[["warm_white"]].
Inside renderPlot(), the scale_*_nd()
scales paint the figure from the same palette the page uses. They take a
palette argument, so the app’s palette selector can switch
a plot between the default Notre Dame colors and the colorblind-friendly
ordering:
set.seed(113)
df <- data.frame(x = rnorm(120), y = rnorm(120),
group = factor(rep(LETTERS[1:3], length.out = 120)))
ggplot(df, aes(x, y, color = group)) +
geom_point(size = 2, alpha = 0.85) +
scale_color_nd(palette = "nd_cvd") +
labs(color = NULL)For a Shiny app that leans on plain HTML rather than Bootstrap components, the package’s R Markdown stylesheet can be included directly, which also sets the soft Warm White page background:
The app’s palette selector exposes the three palettes; the catalog behind them is shown here in full, with a note on what each group is for.
"nd")Thirteen data colors: six leading brand colors that read clearly on
white, then seven former Notre Dame colors to extend the set past six.
This is the palette scale_*_nd() uses by default.
pal <- nd_palette()
named <- nd_colors[match(pal, nd_colors$hex), ]
show_palette(pal, labels = named$name)"nd_cvd")The same Notre Dame colors, reordered so the first several stay
distinguishable under simulated deuteranopia, protanopia, and
tritanopia. Ten anchors, leading with the CVD-safe ND Blue and Bright
Gold. Reach for it with scale_color_nd(palette = "nd_cvd")
when colorblind safety matters more than leading with the brand
colors.
"former")Seven historical brand colors, no longer in the current brand guide, kept to widen the categorical palette. They are approximate, legacy colors and should not be read as current Notre Dame colors.
nd_tints holds the four official near-white Notre Dame
tints, for page or panel backgrounds, fills, and the light end of a
sequential ramp. They are too light to read as data colors and are never
returned by nd_palette().
nd_tints
#> warm_white light_warm_white medium_sky_blue light_sky_blue
#> "#efe9d9" "#f8f4ec" "#e1e8f2" "#edf2f9"nd_informal_tints holds four warm backgrounds, from a
light warm white to a warmer soft yellow. These are not
Notre Dame brand colors; they are alternatives to a white background
(the example app offers white, soft white, and soft yellow).
nd_colors is the complete reference: every color the
package knows about, labeled with its brand (University, Athletics, or
none for the informal backgrounds) and its role. nd_color()
pulls any of them out by name or by role.
nd_colors
#> name key hex brand role
#> 1 ND Blue navy #0c2340 university primary
#> 2 ND Metallic Gold metallic_gold #ae9142 university primary
#> 3 Medium Blue medium_blue #143865 university secondary
#> 4 Bright Blue bright_blue #1c4f8f university secondary
#> 5 Dark Gold dark_gold #8c7535 university secondary
#> 6 Bright Gold bright_gold #d39f10 university secondary
#> 7 Green green #0a843d university secondary
#> 8 Light Green light_green #b3dac5 university secondary
#> 9 Dark Sky Blue dark_sky_blue #c1cddd university secondary
#> 10 Warm White warm_white #efe9d9 university tint
#> 11 Light Warm White light_warm_white #f8f4ec university tint
#> 12 Medium Sky Blue medium_sky_blue #e1e8f2 university tint
#> 13 Light Sky Blue light_sky_blue #edf2f9 university tint
#> 14 Teal teal #36deb8 university former
#> 15 Maroon maroon #4c1c2a university former
#> 16 Purple purple #342551 university former
#> 17 Light Olive light_olive #a8a600 university former
#> 18 Dark Olive dark_olive #456300 university former
#> 19 Pale Yellow pale_yellow #e3e361 university former
#> 20 Black black #1e1a13 university former
#> 21 Faint White faint_white #fdfcfa none informal
#> 22 Soft White soft_white #faf7f1 none informal
#> 23 Faint Yellow faint_yellow #fefdf3 none informal
#> 24 Soft Yellow (light) soft_yellow_light #fdf9e6 none informal
#> 25 Soft Yellow soft_yellow #faf3d7 none informal
#> 26 Soft Yellow (warm) soft_yellow_warm #f6edc6 none informal
#> 27 Notre Dame Blue athletics_blue #0c2340 athletics primary
#> 28 Standard Dome Gold dome_gold #c99700 athletics primary
#> 29 Metallic Dome Gold metallic_dome_gold <NA> athletics primary
#> 30 Irish Green irish_green #00843d athletics secondary
#> 31 White athletics_white #ffffff athletics neutral
#> white_safe pms
#> 1 TRUE 289
#> 2 TRUE 10127
#> 3 TRUE 2154
#> 4 TRUE 2945
#> 5 TRUE 4495
#> 6 TRUE 117
#> 7 TRUE 347
#> 8 TRUE 2246
#> 9 TRUE 5376
#> 10 FALSE 4545
#> 11 FALSE 9064
#> 12 FALSE 650
#> 13 FALSE 656
#> 14 TRUE <NA>
#> 15 TRUE <NA>
#> 16 TRUE <NA>
#> 17 TRUE <NA>
#> 18 TRUE <NA>
#> 19 TRUE <NA>
#> 20 TRUE <NA>
#> 21 FALSE <NA>
#> 22 FALSE <NA>
#> 23 FALSE <NA>
#> 24 FALSE <NA>
#> 25 FALSE <NA>
#> 26 FALSE <NA>
#> 27 TRUE 289
#> 28 TRUE 117
#> 29 NA 8642
#> 30 TRUE 348
#> 31 FALSE <NA>
#> description
#> 1 Primary. The signature Notre Dame Blue.
#> 2 Primary. The metallic Notre Dame Gold.
#> 3 Secondary. A deep blue between ND Blue and Bright Blue.
#> 4 Secondary. A bright mid blue.
#> 5 Secondary. A muted, darker gold.
#> 6 Secondary. A saturated gold; the anchor gold of the data palette.
#> 7 Secondary. The Notre Dame green.
#> 8 Secondary. A pale, soft green.
#> 9 Secondary. The one sky blue dark enough to use as a data color.
#> 10 Near-white tint. A warm cream for page backgrounds.
#> 11 Near-white tint. A lighter warm cream.
#> 12 Near-white tint. A pale blue.
#> 13 Near-white tint. The lightest pale blue.
#> 14 Former secondary Notre Dame color. A bright teal.
#> 15 Former secondary Notre Dame color. A deep maroon (dark brownish red).
#> 16 Former tertiary Notre Dame color; the only former color of the tertiary tier. A dark violet purple.
#> 17 Former secondary Notre Dame color. A yellow-green olive.
#> 18 Former secondary Notre Dame color. A dark olive green.
#> 19 Former secondary Notre Dame color. A soft chartreuse yellow.
#> 20 Former secondary Notre Dame color. A warm near-black.
#> 21 Informal background (not an ND brand color). A warm white just off pure white.
#> 22 Informal background (not an ND brand color). A soft warm white.
#> 23 Informal background (not an ND brand color). A soft yellow just off pure white.
#> 24 Informal background (not an ND brand color). A light, soft warm yellow.
#> 25 Informal background (not an ND brand color). A soft yellow.
#> 26 Informal background (not an ND brand color). A warmer soft yellow.
#> 27 Athletics. Notre Dame Blue, shared with the University.
#> 28 Athletics. The warmer Standard Dome Gold.
#> 29 Athletics. Metallic Dome Gold; a Pantone metallic ink with no digital hex.
#> 30 Athletics. Irish Green, one Pantone step from the University green.
#> 31 Athletics. White.