Dynamic Presentations with Quarto

Myles Mitchell @ Jumping Rivers

Welcome!

Virtual environment

https://quarto-rss.jumpingrivers.training/welcome/

Password: passionfruit-pineapple

Screenshot of log in page

Before we start…

Who am I?

  • Background in Astrophysics & Data Science.

  • Principal Data Scientist @ Jumping Rivers:

    • Project management.

    • Python & ML support for clients.

    • Maintain and teach courses in Python, SQL, ML.

  • Enjoy hiking and travelling.

Jumping Rivers

↗ jumpingrivers.com   𝕏 @jumping_uk

  • Machine learning
  • Dashboard development
  • R packages and APIs
  • Data pipelines
  • Code review
     

Introduction to Quarto

Some context…

  • JR is an official partner of Posit, who maintain:

    • RStudio IDE
    • Posit Connect - host apps and APIs
    • Posit Workbench - running code in the cloud
    • Posit Package Manager - R / Python package management

Posit frameworks

  • Posit maintains free and open source frameworks including:

    • Quarto - automated reporting
    • Shiny - interactive web apps
    • Vetiver - MLOps framework
  • Compatible with R, Python and more!

What is Quarto?

  • “Next-gen” R Markdown: documents that combine code with text.
  • Tables and plots can be quickly regenerated if the data changes.
  • Works for multiple languages and formats (Quarto gallery).
  • These HTML slides were built in Quarto!
  • Quarto files have .qmd extension.
  • Download it from quarto.org/docs/get-started.
Workflow diagram starting with a qmd file, then Jupyter, then md, then pandoc, then PDF, MS Word, or HTML.

Compatible with multiple IDEs

  • RStudio IDE1
  • VS Code2
  • Jupyter
  • Text Editor

Why choose Quarto over R Markdown?

  • Multi-language and multi-engine.
  • User friendly, no requirement for R, easy web hosting.
  • Combines functionality of R Markdown, bookdown, distill, etc into a single CLI.
  • New features will be added to Quarto.
  • Custom formats using extensions.
   

Our first Quarto document

Creating a new Quarto document

  • In RStudio

  • File > New File > Quarto Document

  • Set title and author

  • Click Create

  • Save and click Render

Visual vs Source

  • Quarto has a visual mode to make it feel more like you’re editing a Word document

  • For this workshop we will use the source mode and edit the qmd source code directly

  • See the “Source” and “Visual” buttons above the file editor window

Quarto document structure

  • All Quarto documents have:

    • YAML header - configuration

    • Markdown - document body

YAML header

YAML: Yet Another Markup Language

---
title: "A very cool title"
author: "Myles Mitchell"
format: revealjs
---
  • Set title, subtitle, date, author, etc.
  • Set the output format (pdf, html, revealjs, …).
  • Any formatting that should be applied to the entire document.

Presentation formats

  • Revealjs - HTML, interactive, optimised for web

  • PowerPoint

  • Beamer - LaTeX presentation

Revealjs

  • Open source HTML presentation framework

  • Anything you can do on the web, you can do in your presentation

    • CSS styling

    • Interactive visualisations

    • Even Shiny apps…

  • A lot of features, we won’t get through them all!

Declaring new slides

  • In the Markdown body

  • Use single or double hash to start a new slide

# I am a title slide

## I am a standard slide

I am a title slide

Declaring new slides

  • In the Markdown body

  • Use single or double hash to start a new slide

# I am a title slide

## I am a standard slide

I am a standard slide

Task 1: Your first Quarto presentation

  1. File > New File… > Quarto Presentation

  2. Save to the “dynamic_presentations_with_quarto/” folder

  3. Update the YAML header:

---
title: "A very cool title"
author: "Me"
format: revealjs
---
  1. Add one title slide and two normal slides

  2. Click Render

Quarto basics

Applicable to ANY output format (PDF, HTML, revealjs, …)

Markdown body

  • Text
  • Links
  • Images
  • Code
  • Embedded tables and plots
  • References

Inserting text - Markdown

  • Fonts

    **bold**
    *italic*
  • Headings

    # Heading level 1
    ## Heading level 2
    ### Heading level 3
    #### Heading level 4
    ##### Heading level 5
    ###### Heading level 6
  • Bullet points (use -, + or *)

    - Banana
    - Pear
    - Apple
  • Numbered lists (automatic indexing!)

    1. Royal Gala
    1. Pink Lady
    1. Granny Smith

Including images

  • Use the Visual editor - click Insert –> Figure/Image

  • Or type into a Quarto document:

    ![](img/lemur.jpg){fig-alt="Brown-collared lemur"}

Brown-collared lemur looking directly at the camera

Task 2: Adding Markdown text

  • Add a slide containing some bullet points.

  • Add a second slide with a link to the Duke Lemur Center https://lemur.duke.edu/.

  • Add the image of the Mongoose Lemur (mongoose-lemur.png).

Including code chunks

  • Quarto allows us to combine plain text and code

  • The code can be executed when the document is rendered

  • Plots and figures can be dynamically generated

Loading data

Let’s load some data using R:

```{r}
#| message: false
library(readr)
lemurs <- read_csv(
  "https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2021/2021-08-24/lemur_data.csv",
  col_types = cols_only(sex = "c", age_at_wt_mo = "d", weight_g = "d"))
```

Chunk options

  • Hide the code:

    #| echo: false
  • Don’t evaluate the code:

    #| eval: false
  • Hide code messages:

    #| message: false
  • Output to the current slide:

    #| output-location: slide
  • Can set default code behaviour in the YAML header:

    ---
    title: "My Document"
    author: "Myles Mitchell"
    format: html
    execute:
      message: false
    ---

Code collapsing

If we’re just loading in packages, perhaps we should collapse the code…

Code
```{r}
#| message: false
#| code-fold: true
library(dplyr)
library(tidyr)
library(ggplot2)
```

… do some data wrangling, and print the output as a table…

```{r}
#| output-location: slide 
df = lemurs |>
  drop_na() |>
  filter(age_at_wt_mo > 12)

df |>
  head() |>
  knitr::kable()
```
sex weight_g age_at_wt_mo
M 1086 125.82
M 1190 129.93
F 947 131.11
F 1174 135.42
M 899 100.64
M 917 101.06

…or include some exploratory plots!

```{r}
#| message: false
#| output-location: slide
#| fig-cap: "Age vs weight of lemurs"
#| fig-alt: "Scatter plot showing positive relationship between lemur age and weight split by sex"
#| out-width: 150%
ggplot(data = df,
       mapping = aes(x = age_at_wt_mo,
                     y = weight_g,
                     colour = sex)) +
  geom_point(alpha = 0.1) +
  geom_smooth(method = "lm") +
  labs(title = "Weight of lemurs",
       x = "Age (months)",
       y = "Weight (g)")
```

Scatter plot showing positive relationship between lemur age and weight split by sex

Age vs weight of lemurs

Inline code

```{r}
num_obs = nrow(lemurs)
```

We can also include code inline, rather than as a separate chunk.

The number of observations is `r num_obs`.

The number of observations is 82609.

Multi-language support

  • You can also include Python code chunks!

  • Fence code cells with {python} instead of {r}.

  • VS Code and Jupyter are both supported by Quarto.

  • Inline code has a different syntax in Python.

  • See Python Quarto docs: quarto.org/docs/computations/python.html

Task 3: Adding code

  • In a new slide, add a code block to load the data and libraries (see task-3.R chunk 1).

  • Hide any output messages from the code chunk.

  • In the next slide, add a hidden code chunk which generates a scatter plot (see task-3.R chunk 2).

  • Add a caption to the plot with the fig-cap code chunk option.

  • In the next slide, add a final code chunk to output the average weight.

Polished presentations

Incremental lists

  • Use a “div” of class “.incremental” (familiar to users of HTML / CSS)
:::{.incremental}
- Adelie
- Gentoo
- Chinstrap
:::
  • Adelie
  • Gentoo
  • Chinstrap

Incremental lists

  • Set all lists to be incremental:
format:
  revealjs:
    incremental: true
  • Override with a non-incremental div:
:::{.nonincremental}
- Adelie
- Gentoo
- Chinstrap
:::

Column layouts

::::{.columns}

:::{.column width="70%"}
Content for my left column
:::

:::{.column width="30%"}
Content for my right column
:::

::::
  • You can have as many columns as you want!

Code highlighting

  • Highlight / step through lines of code in chunks

  • Use the code-line-numbers option

Code highlighting

```{python}
#| code-line-numbers: "3"
def add(x, y):
  d = x + y 
  return d
```

Code highlighting

```{python}
#| code-line-numbers: "3,4"
def add(x, y):
  d = x + y 
  return d
```

Code highlighting

```{python}
#| code-line-numbers: "3|4,5"
def add(x, y):
  d = x + y 
  return d
```

Extensions

  • Add an “_extensions” folder

  • Allows to define custom styles using CSS

  • Set the font types, font sizes, font colours, background colours, logo, and more

  • Easy to share within your team (useful for branded presentations)

Task 4: Styling and formatting

  • Change the output format to jrSlides-revealjs - this uses the _extensions/jrSlides/ folder provided

  • Add a slide with two columns (60% and 40% width):

    • Include bullet points in the left column

    • Add the Mongoose Lemur image to the right column

  • In one of the code slides, use code line highlighting

Thanks for listening!

Any questions?

Come say hi!

  • Visit us at the Jumping Rivers stand

Shiny In Production 2025

  • Join us for Shiny In Production (8-9 Oct), Newcastle Upon Tyne

  • shiny-in-production.jumpingrivers.com

  • A half day of workshops followed by a day of talks on all things Shiny

  • Discount code (30% off): RSS2025

Free monthly webinars

  • Jumping Rivers is organising free, monthly webinars!

  • Upcoming topics include Scalable Shiny Apps, Machine Learning with Python, Introduction to the Posit Ecosystem

  • Next webinar: 18 September

  • Find out more at jumpingrivers.com/blog/jumping-rivers-webinar-launch/

  • Follow “Jumping Rivers Ltd” on LinkedIn to keep up to date

Bonus content

Publishing Quarto documents

It’s easy to share your documents!

  • Quarto Pub is free to use for public documents and sites.

  • Hosting public HTML sites via GitHub pages (available to free GitHub accounts).

  • Publish to Posit Connect for restricted visibility.

  • Top tip: creating an HTML with no external dependencies

    ---
    title: "Presentation with embedded images"
    format:
      revealjs:
        embed-resources: true
    ---