Exercise 11 — PMAP 8551/4551, Fall 2025

Author

Andrew Heiss

Published

November 10, 2025

Hopefully you did something neat!

There are so many things you can do with Quarto websites and interactivity! See my whole workshop on Quarto websites for a ton of different examples.

For fun, here are two super extra fancy ways to do more interactive stuff with Quarto.

Use the “Code” button up at the top of this page to see the full .qmd for this page.

OJS and Observable Plot

Observable JS is a Javascript-based way to analyze and visualize data. Because it’s Javascript, it runs in your browser and updates live. Quarto supports OJS natively, and you can even make R (or Python) chunks feed into OJS chunks.

For instance, this is R code:

library(tidyverse)

penguins <- datasets::penguins |> 
  drop_na(sex)

# Make the penguins data available to Observable JS
ojs_define(penguins = penguins)

This is NOT R code! This is Observable JS code!

Code
viewof species = Inputs.checkbox(
  ["Adelie", "Chinstrap", "Gentoo"], 
  { value: ["Adelie", "Gentoo"], 
    label: "Species:"
  }
)

// Rotate the data so that it works with OJS
penguins_js = transpose(penguins)

// Filter the data based on the selected species
penguins_filtered = penguins_js.filter(d => species.includes(d.species))

// Plot this thing
Plot.plot({
  color: {
    domain: ["Adelie", "Chinstrap", "Gentoo"],
    range: ["#FF8C00", "#A020F0", "#008B8B"]
  },
  symbol: {
    domain: ["Adelie", "Chinstrap", "Gentoo"],
    range: ["circle", "triangle", "square"]
  },
  marks: [
    Plot.dot(penguins_filtered, {
        x: "bill_dep", y: "bill_len", fill: "species", symbol: "species", r: 6,
        tip: true
      }
    )
  ]}
)

Quarto Live

The Quarto Live extension lets you run R chunks directly in your browser. This is how the R Primers work (remember those from the beginning of the semester?!)

One super neat thing about Quarto Live is that you can use OJS inputs to feed data into live R chunks.

Here’s OJS code for creating the interactive inputs:

Code
numeric_vars = ["bill_len", "bill_dep", "flipper_len", "body_mass"]
categorical_vars = ["species", "island", "sex"]

viewof species_filter = Inputs.checkbox(
  ["Adelie", "Chinstrap", "Gentoo"],
  {label: "Species to include", value: ["Adelie", "Chinstrap", "Gentoo"]}
)

viewof x_var = Inputs.select(numeric_vars, {
  label: "X Variable",
  value: "bill_len"
})

viewof y_var = Inputs.select(numeric_vars, {
  label: "Y Variable",
  value: "bill_dep"
})

viewof color_var = Inputs.select(categorical_vars, {
  label: "Color by",
  value: "species"
})

viewof show_trend_species = Inputs.toggle({
  label: "Show species trends",
  value: false
})

viewof show_trend_overall = Inputs.toggle({
  label: "Show overall trend",
  value: false
})

And here’s a live R chunk using ggplot to plot the penguins data. It automatically reruns when you change the inputs above, and it all happens right in your browser!