library(tidyverse)
library(plotly)
library(palmerpenguins)
<- penguins |> drop_na(sex)
penguins
<- ggplot(penguins, aes(x = bill_length_mm, y = body_mass_g, color = species)) +
basic_plot geom_point()
ggplotly(basic_plot)
Session 11 tips and FAQs
Hi everyone!
Great work with your dashboards! Quarto dashboards are a super new feature (like, they were only added in January 2024), and you’re one of the first R classes to make them as part of an assignment. You’re on the cutting edge!
Just a few quick FAQs and tips for this session:
Do people use Plotly and Quarto dashboards in the real world?
In the lecture I mentioned that most COVID dashboards were/are made with Shiny or {flexdashboard}. Both are still extremely popular and you’ll see Shiny and {flexdashboard} websites all over the internet.
Organizations have been moving to Quarto too. In November 2024, Idaho launched a new election results dashboard for its general election results and it’s 100% built with Quarto and Plotly.
And now you can all do similar, real world things too!
My plot didn’t translate perfectly to ggplotly—why?
In session 11 you used ggplotly()
to convert a ggplot object into an interactive plot, which I think is magical:
However, lots of you discovered that Plotly does not translate everything perfectly. Plotly is a separate Javascript library and it doesn’t support every option ggplot does. ggplotly()
tries its best to translate between R and Javascript, but it can’t get everything. For instance, subtitles, captions, and labels disappear:
<- ggplot(penguins, aes(x = bill_length_mm, y = body_mass_g, color = species)) +
fancy_plot geom_point() +
annotate(geom = "label", x = 50, y = 5500, label = "chonky birds") +
labs(title = "Penguin bill length and weight",
subtitle = "Neato",
caption = "Here's a caption")
ggplotly(fancy_plot)
That’s just a limitation with ggplot and plotly. If you want a perfect translation, you’ll need to hack into the guts of the translated Javascript and HTML and edit it manually to add those things.
Alternatively, you can check out other interactive plot packages. {ggiraph} makes really great and customizable interactive plots (and it supports things like subtitles and captions and labels and other annotations ggplotly can’t), but with slightly different syntax:
library(ggiraph)
<- ggplot(data = penguins) +
plot_thing geom_point_interactive(aes(x = bill_length_mm, y = body_mass_g, color = species,
tooltip = species, data_id = species)) +
annotate(geom = "label", x = 50, y = 5500, label = "chonky birds") +
labs(title = "Penguin bill length and weight",
subtitle = "Neato",
caption = "Here's a caption")
girafe(ggobj = plot_thing)
I tried to render a dashboard but it appeared as a regular HTML file—why?
Lots of you submitted a dashboard for Task 3 that looked like a regular HTML file, like this:
That’s because the document was missing the format: dashboard
option, which tells Quarto to render it in a special dashboard-y way. Your top metadata probably looked like this:
---
title: "Some title"
---
## Row
```{r}
#| warning: false
#| message: false
library(tidyverse)
ggplot(mpg, aes(x = displ, y = hwy)) +
geom_point()
```
To fix it, add format: dashboard
to the metadata area:
---
title: "Some title"
format: dashboard
---
It should now look like this:
When should we use a dashboard vs. a full Shiny app?
Shiny is a really neat R package that lets you run fully interactive web applications in a browser. It runs R code behind the scenes to calculate stuff and generate plots, and it’s powerful and cool.
But it also is complex and requires a full server to run. You can’t just render a .qmd file as a Shiny app and share the resulting HTML with someone—you can’t even publish Shiny apps to Quarto Pub (you can publish it to shinyapps.io, but they only let you have one free app, since they’re so resource intensive).
You need to use Shiny if you need things to be recalculated on the page, like if you want users to change some settings and have those be reflected in a plot, or if you want the page to show the latest version of live data from some remote data source. Because R runs behind the scenes, it’ll redraw plots and re-import data and rebuild parts of the web page as needed.
If you don’t need things to be reclaculated on the page, you can just use a regular dashboard, like in Exercise 11. There’s no need for fancy server backend stuff—nothing needs to be recalculated or replotted or anything.
If you have things that need to be recalculated/replotted and you don’t want to use Shiny (which is totally understandable! it’s a tricky complex package!), Quarto has support for something called Observable JS, which is essentially a Javascript version of {ggplot2} and {dplyr} and R. It runs stuff directly in your browser without needing a whole server—documents with Observable JS (OJS) chunks can be published on Quarto Pub. You can even mix R and OJS chunks in the same document.
Like, watch this magic.
Here’s an R chunk that loads gapminder data and penguin data and then makes them available to OJS:
```{r}
library(gapminder)
library(palmerpenguins)
ojs_define(gapminder = gapminder, penguins = palmerpenguins::penguins)
```
And here’s an OJS chunk that filters the gapminder data and plots it in an interactive way. You can slide that year slider and have it replot things automatically—no need for Shiny!
This is NOT R code! This is Observable JS code!
{ojs}
```//| echo: fenced
= Inputs.range(
viewof current_year [1952, 2007],
{value: 1952, step: 5, label: "Year:"}
)
// Rotate the data so that it works with OJS
= transpose(gapminder)
gapminder_js
// Filter the data based on the selected year
= gapminder_js.filter(d => d.year == current_year)
gapminder_filtered
// Plot this thing
.plot({
Plot: {type: "log"},
x: [
marks.dot(gapminder_filtered, {
Plot: "gdpPercap", y: "lifeExp", fill: "continent", r: 6,
x: {
channels: d => d.country
Country},
: true
tip}
)
]}
)
```
And here’s an OJS plot that filters the penguins data based on user input and plots it as facetted histograms:
{ojs}
```//| echo: fenced
= Inputs.range(
viewof bill_length_min [32, 50],
{value: 35, step: 1, label: "Bill length (min):"}
)
= Inputs.checkbox(
viewof islands ["Torgersen", "Biscoe", "Dream"],
{ value: ["Torgersen", "Biscoe"],
: "Islands:"
label}
)
// Rotate the data so that it works with OJS
= transpose(penguins)
penguins_js
// Filter the data
= penguins_js.filter(function(penguin) {
filtered return bill_length_min < penguin.bill_length_mm &&
.includes(penguin.island);
islands})
// Plot the data
.rectY(filtered,
Plot.binX(
Plot{y: "count"},
{x: "body_mass_g", fill: "species", thresholds: 20}
))
.plot({
: {
facet: filtered,
data: "sex",
x: "species",
y: 80
marginRight},
: [
marks.frame(),
Plot]
}
)
```
That’s so cool!
You can do a ton of neat interactive things—without Shiny!—with Observable JS. See these, for instance:
I rendered my file / dashboard but it didn’t appear in the Viewer panel—why not?
When you render a Quarto file, RStudio will show you a preview of it. Depending on how RStudio is set up, that preview can appear in the Viewer panel, or it can appear in a separate web browser window. Both options are helpful and I use them interchangeably—if I’m at home with my wider monitor, I’ll have the preview appear in a separate window on the side of my screen; if I’m just on my laptop, I’ll have the preview appear in the Viewer panel.
You can control where it appears with the little gear icon next to the “Render” button in RStudio:
There are other options there too. If you don’t like having plots appear underneath chunks inside your document, you can tell it to show “Chunk Output in Console”. This will put plots in the Plots panel instead.
Do people use viridis palettes in real life?
Yes! Now that you know what the viridis palettes look like, you’ll notice them in all sorts of reports and papers and visualizations.
For instance, check out this paper on black hole plasma—that’s the “magma” scale:
They pop up in fiction too! In S4E5 of The Expanse (and throughout the show, actually), you can see charts on futuristic iPads using the “plasma” scale:
Back in March 2020 I even found a wild scale_color_viridis_d()
on my kitchen counter :)
I’m bored with ggplot’s default colors and/or viridis—how can I use other color palettes?
There’s a guide to using all sorts of different colors, including how to use fancy scientifically-designed palettes, custom colors from organizations like GSU, and colors from art, music, movies and TV shows, and historical events. You can make gorgeous plots with these different colors!