Quarto
Dashboards

Hello, Dashboards!

  • Hello, Dashboards!

  • Dashboard basics

  • First dashboard

  • Layout

  • Dashboard components

Quarto ➝ many outputs

With Quarto you can weave together narrative text and code to produce elegantly formatted output as documents, web pages, blog posts, books, and more…

Quarto ➝ dashboards

🌎 World Happiness Report dashboard

Notebook ➝ Dashboard

olympicdash.qmd
---
title: "World Happiness Report"
format: dashboard
---

# notebook content goes here...

Dashboard basics

  • Hello, Dashboards!

  • Dashboard basics

  • First dashboard

  • Layout

  • Dashboard components

Cards

Dashboards are composed of cards.

Rows and columns

Cards are arranged into rows and columns.

Layouts

Pages, tabsets, and sidebars allow for more advanced layouts.

Step-by-step

Let’s make a dashboard, step-by-step

First dashboard

  • Hello, Dashboards!

  • Dashboard basics

  • First dashboard

  • Layout

  • Dashboard components

Step 1: format: dashboard

dashboard.qmd
---
title: "My first Quarto dashboard"
format: dashboard
---

Step 2: Add a card

dashboard.qmd
---
title: "My first Quarto dashboard"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point
from plotnine.data import mpg
```

```{python}
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

Step 2: Add a card

dashboard.qmd
---
title: "My first Quarto dashboard"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point
from plotnine.data import mpg
```

```{python}
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

Step 3: Add another card

dashboard.qmd
---
title: "My first Quarto dashboard"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

```{python}
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

```{python}
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Step 3: Add another card

dashboard.qmd
---
title: "My first Quarto dashboard"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

```{python}
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

```{python}
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Step 4: Add titles to cards

dashboard.qmd
---
title: "My first Quarto dashboard"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Step 4: Add titles to cards

dashboard.qmd
---
title: "My first Quarto dashboard"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Steps 1 - 4

brand.yml works with dashboards too!

Your turn

  1. Open dashboard-r.qmd or dashboard-python.qmd.
  2. Change the format from html to dashboard.
  3. Re-render.
  4. Add relevant titles to each card.

The brand.yml file should be automatically applied!

03:00

Layout

  • Hello, Dashboards!

  • Dashboard basics

  • First dashboard

  • Layout

  • Dashboard components

Rows

By default, cards are laid out in rows:

dashboard.qmd
---
title: "Rows"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

## Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Rows

dashboard.qmd
---
title: "Rows"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

## Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Rows

Default value of orientation is rows:

dashboard.qmd
---
title: "Rows"
format: 
  dashboard:
    orientation: rows
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

## Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Columns

Setting orientation to columns makes each ## indicate a column instead of a row:

dashboard.qmd
---
title: "Columns"
format: 
  dashboard:
    orientation: columns
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

## Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Columns

dashboard.qmd
---
title: "Columns"
format: 
  dashboard:
    orientation: columns
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

## Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Rows, then columns

dashboard.qmd
---
title: "Rows, then columns"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Overview

### 

This dashboard summarizes an illuminating analysis of fuel economy of cars.

### 

This is a car.

![](images/car.png){fig-alt="Illustration of a teal color car."}

## Plots

### Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

### Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Rows, then columns

dashboard.qmd
---
title: "Rows, then columns"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Overview

### 

This dashboard summarizes an illuminating analysis of fuel economy of cars.

### 

This is a car.

![](images/car.png){fig-alt="Illustration of a teal color car."}

## Plots

### Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

### Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Columns, then rows

dashboard.qmd
---
title: "Rows, then columns"
format: 
  dashboard:
    orientation: columns
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Overview

### 

This dashboard summarizes an illuminating analysis of fuel economy of cars.

### 

This is a car.

![](images/car.png){fig-alt="Illustration of a teal color car."}

## Plots

### Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

### Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Columns, then rows

dashboard.qmd
---
title: "Rows, then columns"
format: 
  dashboard:
    orientation: columns
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Overview

### 

This dashboard summarizes an illuminating analysis of fuel economy of cars.

### 

This is a car.

![](images/car.png){fig-alt="Illustration of a teal color car."}

## Plots

### Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

### Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Your turn

Change the layout of your dashboard so that it looks like this:

05:00

Dashboard components

  • Hello, Dashboards!

  • Dashboard basics

  • First dashboard

  • Layout

  • Dashboard components

Quarto dashboards are highly customizable!

Cards

Cards are containers for code cell outputs (e.g., plots, tables, value boxes) and free form markdown text. The content of cards typically maps to cells in your notebook or source document.

Your turn

  1. Take a look at the Tabsets documentation on the Quarto website.

  2. Move the plots showing the countries that increased and decreased in happiness into a tabset. Your dashboard should then look like this:

05:00

Tabsets

dashboard.qmd
---
title: "Tabsets"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Overview {.tabset}

### Objective

This dashboard summarizes an illuminating analysis of fuel economy of cars.

### Car

This is a car.

![](images/car.png){fig-alt="Illustration of a teal color car." width="299"}

## Plots {.tabset}

### Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

### Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Tabsets

Each card within a row/column or each row/column within another becomes a tab:

dashboard.qmd
---
title: "Tabsets"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Overview {.tabset}

### Objective

This dashboard summarizes an illuminating analysis of fuel economy of cars.

### Car

This is a car.

![](images/car.png){fig-alt="Illustration of a teal color car." width="299"}

## Plots {.tabset}

### Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

### Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Pages

dashboard.qmd
---
title: "Pages"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

# Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

# Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Pages

dashboard.qmd
---
title: "Pages"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

# Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

# Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Pages

dashboard.qmd
---
title: "Pages"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

# Scatter

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

# Bar

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Value boxes

  • Value boxes are a great way to prominently display simple values within a dashboard

  • You can create value boxes in executable cells or plain markdown in divs

  • Value boxes use Bootstrap icons (https://icons.getbootstrap.com) and can be set to any color (e.g., with a HEX code) or color alias defined by the theme.

    Color alias Default theme color(s)
    primary Blue
    secondary Gray
    success Green
    info Bright Blue
    warning Yellow/Orange
    danger Red
    light Light Gray
    dark Black

Value boxes

dashboard.qmd
---
title: "Valueboxes"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Value boxes {height="25%"}

```{python}
#| label: calculate-values
lowest_mileage_index = mpg['cty'].idxmin()
lowest_mileage_car = mpg.iloc[lowest_mileage_index]
lowest_mileage_cty = mpg.loc[lowest_mileage_index, 'cty']

highest_mileage_index = mpg['cty'].idxmax()
highest_mileage_car = mpg.iloc[highest_mileage_index]
highest_mileage_cty = mpg.loc[highest_mileage_index, 'cty']

mean_city_mileage = mpg['cty'].mean()
rounded_mean_city_mileage = round(mean_city_mileage, 2)
```

```{python}
#| content: valuebox
#| title: "Least efficient"
#| icon: fuel-pump-fill
#| color: danger
dict(
  value = str(f"{lowest_mileage_cty} mpg")
)
```

```{python}
#| content: valuebox
#| title: "Most efficient"
dict(
  icon = "fuel-pump",
  color = "success",
  value = str(f"{highest_mileage_cty} mpg")
)
```

::: {.valuebox icon="fuel-pump" color="secondary"}
Average city mileage

`{python} str(rounded_mean_city_mileage)` mpg
:::

## Plots {height="75%"}

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Value boxes

dashboard.qmd
---
title: "Valueboxes"
format: dashboard
---

```{python}
from plotnine import ggplot, aes, geom_point, geom_bar
from plotnine.data import mpg
```

## Value boxes {height="25%"}

```{python}
#| label: calculate-values
lowest_mileage_index = mpg['cty'].idxmin()
lowest_mileage_car = mpg.iloc[lowest_mileage_index]
lowest_mileage_cty = mpg.loc[lowest_mileage_index, 'cty']

highest_mileage_index = mpg['cty'].idxmax()
highest_mileage_car = mpg.iloc[highest_mileage_index]
highest_mileage_cty = mpg.loc[highest_mileage_index, 'cty']

mean_city_mileage = mpg['cty'].mean()
rounded_mean_city_mileage = round(mean_city_mileage, 2)
```

```{python}
#| content: valuebox
#| title: "Least efficient"
#| icon: fuel-pump-fill
#| color: danger
dict(
  value = str(f"{lowest_mileage_cty} mpg")
)
```

```{python}
#| content: valuebox
#| title: "Most efficient"
dict(
  icon = "fuel-pump",
  color = "success",
  value = str(f"{highest_mileage_cty} mpg")
)
```

::: {.valuebox icon="fuel-pump" color="secondary"}
Average city mileage

`{python} str(rounded_mean_city_mileage)` mpg
:::

## Plots {height="75%"}

```{python}
#| title: Highway vs. city mileage
(
    ggplot(mpg, aes(x = "cty", y = "hwy"))
    + geom_point()
)
```

```{python}
#| title: Drive types
(
    ggplot(mpg, aes(x = "drv"))
    + geom_bar()
)
```

Value boxes - R syntax

dashboard.qmd
---
title: "Valueboxes"
format: dashboard
---

```{r}
#| content: valuebox
#| title: "Least efficient"
#| icon: fuel-pump-fill
#| color: danger
list(
  value = paste(lowest_mileage_cty, "mpg")
)
```

```{r}
#| content: valuebox
#| title: "Most efficient"
list(
  icon = "fuel-pump",
  color = "success",
  value = paste(highest_mileage_cty, "mpg")
)
```

::: {.valuebox icon="fuel-pump" color="secondary"}
Average city mileage

30 mpg
:::

Markdown text

  • You can include markdown text anywhere within a dashboard

  • Markdown text is automatically placed in cards, but you can also explicitly put them in cards with fenced divs, and add titles to cards

    ::: {.card title="Title goes here"}
    Text goes here.
    :::
  • You can place markdown text and other cell output in a single card as well

    ::: {.card title="Title goes here"}
    Text goes here.
    
    ```{r}
    # code generating output goes here
    ```
    :::    

Your turn

Add two value boxes to your dashboard, above the tabset, so that your dashboard looks like this:

Use the brand colors. You can either hard-code the value box values (“Finland” and “Social support”) or calculate them using the data.

05:00

…and much more!

There’s much more you can adjust and do with Quarto dashboards, including: