Posit’s New Brand YML Specification for Themes Makes Its Debut!

Shiny for Python leads the way with the first implementation of this powerful brand system

shiny-python
design-systems
web
Author

James Balamuta

Published

November 10, 2024

Brand consistency is a requirement for any organization to maintain a professional image and build trust with its audience. Whether you’re managing a corporate identity, university branding, or open-source project, a unified visual language across all touchpoints reinforces your brand identity and creates a professional impression.

Introducing Posit’s brand-yml Specification

Posit’s new brand-yml specification offers a streamlined solution for maintaining brand consistency throughout your data science applications. This specification provides a structured approach to define and implement brand guidelines across the entire Posit ecosystem.

By centralizing brand definitions in a single configuration file, the specification makes it significantly easier to:

  • Maintain consistent user interfaces across multiple applications
  • Update brand elements without requiring extensive code changes
  • Ensure compliance with organizational brand guidelines
  • Apply themes consistently across different programming languages and frameworks

A Real-World Example: Stanford University

To demonstrate the power of this approach, we’ll implement Stanford University’s comprehensive brand guidelines, which govern everything from logo usage to typography and color schemes. We’ll first define Stanford’s brand system in a _brand.yml file, then apply it to a Shiny for Python app.

Creating the Brand Configuration

Using Posit’s new brand-yml capabilities, let’s create a brand configuration for Stanford University. The process begins with defining Stanford’s visual identity components in a _brand.yml file:

meta:
  name: 
    full: Stanford University
    short: Stanford
  link:
    home: https://www.stanford.edu
    linkedin: https://www.linkedin.com/school/stanford-university/
    facebook: https://www.facebook.com/Stanford/
    twitter: https://x.com/Stanford

color:
  palette:
    cardinal: "#8C1515"  # Stanford Cardinal Red
    cardinal-light: "#B83A4B"
    cardinal-dark: "#820000"
    white: "#FFFFFF"
    black: "#2E2D29"
    cool-grey: "#53565A"
    fog: "#DAD7CB"        # Light tan/beige
    sky: "#007C92"        # Teal blue
    palo-alto: "#175E54"  # Dark green
    poppy: "#e98300"      # Stanford orange
    sandstone: "#D2C295"  # Light tan
    
  primary: cardinal
  secondary: cool-grey
  background: white
  foreground: black
  success: palo-alto
  info: sky
  warning: poppy
  danger: cardinal-dark

typography:
  fonts:
    - source: bunny
      family: "Source Sans Pro"
      weight: [300, 400, 600, 700]
    - source: bunny
      family: "Source Serif Pro"
      weight: [400, 600, 700]

This configuration captures Stanford’s core brand elements, including the official color palette with semantic color assignments and typography specifications using web-accessible fonts.

Implementing in Shiny for Python

Applying the brand system to a Shiny for Python app is straightforward. First, we need to install the necessary package with theme support:

pip install "shiny[theme]"

This installs a sass dependency for compiling the underlying SCSS files that define the branded theme.

Basic Example

Here’s how to apply the Stanford brand theme to a simple Shiny app:

from shiny import App, ui
from pathlib import Path

# Retrieve the brand theme
theme = ui.Theme.from_brand(Path(__file__))

app_ui = ui.page_fixed(
    ui.h1("Dashboard"), # Create Title
    ui.card(
        "Sample content for demonstration",
        class_="bg-primary text-secondary" # Assign using bootstrap colors the "primary"
    ),
    theme = theme  # Apply the brand theme
)

app = App(app_ui, None)

Try it in the Shiny Playground

from shiny.express import ui
from pathlib import Path

# Apply the brand theme
ui.page_opts(theme=ui.Theme.from_brand(Path(__file__)))

# Create header with Stanford branding
ui.h1("Stanford Dashboard", class_="text-cardinal")

# Create the card with primary color background
with ui.card(class_="bg-primary text-white"):
    "Sample content for demonstration"

Try it in the Shiny Playground

Using Theme Colors in Visualizations

One of the key advantages of the brand-yml system is the ability to use brand colors consistently across all aspects of your application, including data visualizations. Plotly, Matplotlib, and other visualization libraries can utilize these colors to maintain brand consistency.

Accessing Theme Colors

To use theme colors in visualizations, you need to access them through the theme’s brand attribute:

# Load the Stanford brand theme
theme = ui.Theme.from_brand(Path(__file__).parent)

# Access palette colors through the brand object
cardinal_red = theme.brand.color.palette.get("cardinal")
sky_blue = theme.brand.color.palette.get("sky")
cool_grey = theme.brand.color.palette.get("cool-grey")

# Access semantic colors directly
primary_color = theme.brand.color.primary
secondary_color = theme.brand.color.secondary
success_color = theme.brand.color.success

Using With Plotly

For Plotly visualizations, you can use the brand colors in the color_discrete_sequence parameter:

# Create a list of Stanford brand colors for visualizations
stanford_colors = [
    theme.brand.color.palette.get("cardinal"),    # Stanford's signature red
    theme.brand.color.palette.get("sky"),         # Stanford's sky blue
    theme.brand.color.palette.get("cool-grey"),   # Cool grey
    theme.brand.color.palette.get("palo-alto"),   # Dark green
    theme.brand.color.palette.get("poppy")        # Stanford orange
]

# Use in a bar chart
fig = px.bar(data, x="Department", y="Students", 
             color_discrete_sequence=[theme.brand.color.primary])

# Use in a pie chart
fig = px.pie(data, values="Funding", names="Department",
             color_discrete_sequence=stanford_colors)

Using With Matplotlib

For Matplotlib visualizations, you can use the colors directly:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.bar(departments, values, color=theme.brand.color.palette.get("cardinal"))
ax.set_title("Department Statistics", color=theme.brand.color.palette.get("cool-grey"))

Complete Example Application

Let’s bring everything together with a more comprehensive example that showcases Stanford’s branding across a full Shiny application:

from shiny import App, ui, render
from shinywidgets import output_widget, render_widget  
from pathlib import Path
import pandas as pd
import plotly.express as px

# Load the Stanford brand theme
theme = ui.Theme.from_brand(Path(__file__).parent)

# Extract brand colors for visualizations
stanford_colors = [
    theme.brand.color.palette.get("cardinal"),    # Stanford's signature red
    theme.brand.color.palette.get("sky"),         # Stanford's sky blue
    theme.brand.color.palette.get("cool-grey"),   # Cool grey
    theme.brand.color.palette.get("palo-alto"),   # Dark green
    theme.brand.color.palette.get("poppy")        # Stanford orange
]

# Create sample data
data = pd.DataFrame({
    "Department": ["Engineering", "Medicine", "Humanities", "Sciences", "Business"],
    "Students": [450, 380, 210, 320, 290],
    "Funding": [5.2, 4.8, 1.5, 3.7, 2.3]
})

# Define UI
app_ui = ui.page_fluid(
    ui.panel_title("Stanford University Department Analytics"),
    
    ui.page_sidebar(
        ui.sidebar(
            ui.h3("Filters", class_="text-cardinal"),
            ui.input_checkbox_group(
                "departments",
                "Select Departments:",
                choices=data["Department"].tolist(),
                selected=data["Department"].tolist(),
            ),
            ui.input_slider("funding_threshold", "Minimum Funding (millions):", 
                           min=0, max=6, value=0, step=0.5),
            bg=theme.brand.color.palette.get("fog")  # Using Stanford's fog color
        ),
        
        # Disclaimer card with semantic danger color
        ui.card(
            ui.card_header("This data is made up!", class_="bg-danger")
        ),
        
        ui.value_box(
            "Total Students",
            ui.output_text("total_students"),
            showcase=ui.HTML('<i class="fa fa-users"></i>'),
            theme="primary"
        ),
        
        # Main content area
        ui.card(
            ui.card_header("Department Size", class_="bg-cardinal"),
            output_widget("student_plot")
        ),
        ui.card(
            ui.card_header("Funding Distribution", class_="bg-cardinal-dark"),
            output_widget("funding_plot")
        )
    ),
    theme=theme  # Apply the Stanford theme
)

# Define server
def server(input, output, session):
    @render_widget
    def student_plot():
        filtered_data = data[
            (data["Department"].isin(input.departments())) &
            (data["Funding"] >= input.funding_threshold())
        ]
        fig = px.bar(filtered_data, x="Department", y="Students", 
                    color_discrete_sequence=[stanford_colors[0]])
        fig.update_layout(template="simple_white")
        return fig
    
    @render_widget
    def funding_plot():
        filtered_data = data[
            (data["Department"].isin(input.departments())) &
            (data["Funding"] >= input.funding_threshold())
        ]
        fig = px.pie(filtered_data, values="Funding", names="Department",
                    color_discrete_sequence=stanford_colors)
        return fig
    
    @output
    @render.text
    def total_students():
        filtered_data = data[
            (data["Department"].isin(input.departments())) &
            (data["Funding"] >= input.funding_threshold())
        ]
        return f"{filtered_data['Students'].sum():,}"

# Create and run the app
app = App(app_ui, server)

This example demonstrates:

  1. Loading the Stanford theme
  2. Extracting brand colors for visualization consistency
  3. Using semantic color classes (text-cardinal, bg-danger) for UI elements
  4. Direct color usage with theme attributes (bg=theme.brand.color.palette.get("fog"))
  5. Consistent branding across all application components

Try it out in the Shiny Playground

Beyond Shiny: Future Applications

While Shiny for Python is the first to implement the brand-yml specification, Posit plans to extend support to other products in its ecosystem:

  • R Shiny: The specification will be implemented in R Shiny to provide consistent theming across both Python and R applications
  • Quarto: Support for brand-yml in Quarto documents and websites
  • R Markdown: Brand theming will be available for R Markdown documents and reports
  • pkgdown: Branding support will be added to pkgdown websites for R packages

Conclusion

Posit’s brand-yml specification represents a significant advancement in maintaining brand consistency across data science applications. By centralizing brand definitions in a single configuration file, it enables developers to create cohesively branded experiences with minimal effort.

The Stanford example demonstrates how organizations with established brand guidelines can ensure their digital data products maintain brand integrity while leveraging modern web frameworks. The combination of color palettes, typography, and semantic color assignments provides a flexible yet standardized approach to theming.

As this specification matures and expands to more Posit products, we can expect even greater integration and consistency across the entire data science workflow, from exploratory analysis to published reports and interactive applications.