::install("ggplot2")
webr::install("htmltools") #<- only needed to use SVG images webr
2 shiny(live)!
The Quarto doc will contain the shiny
app using a code chunk. The type of code chunk should be {shinylive-r}
(as opposed to {r}
).
2.1 yml options
The main requirement for the code chunk yml is the option standalone: true
.
For my application, I used the options:
```{shinylive-r}
#| label: fig-shiny-spline
#| viewerHeight: 500
#| standalone: true
The label
doesn’t make it a figure as it normally would but see the section below for details regarding this (and details like captions, etc.).
The standard fig-height
(and width) options don’t apply to shiny
apps; viewerHeight
is used instead.
You also have to add a Quarto filter in your _quarto.yml
file:
filters:
- shinylive
There is a bit more to say about formatting the chunk for Quarto but we’ll show that later.
2.2 Package declarations
In our chunk that contains the shiny
app (i.e., fig-shiny-spline
in this example), let’s make sure to install packages that we need (besides shiny
):
The base installation of webR includes its own webr
utility package, so don’t worry about installing that.
2.3 User-interface function
The UI function is very simple and has no extra accouterments for shinylive
<- fluidPage(
ui
fluidRow(
column(8,
sliderInput(
"deg_free",
label = "Spline degrees of freedom:",
min = 3L, value = 3L, max = 8L, step = 1L
)
),
imageOutput("spline_contours", height = "400px")
) )
2.4 The server function
This is where most of the customization happens.
<- function(input, output, session) {
server
# ------------------------------------------------------------------------
# Input data from remote locations on GitHub
1<-
pred_path paste(
"https://raw.githubusercontent.com",
"topepo", "shinylive-in-book-test",
"main", "predicted_values.RData",
sep = "/"
) <-
data_path paste(
"https://raw.githubusercontent.com",
"topepo", "shinylive-in-book-test",
"main", "sim_val.RData",
sep = "/"
)
2<- tempfile()
rdata_file download.file(pred_path, destfile = rdata_file)
load(rdata_file)
download.file(data_path, destfile = rdata_file)
load(rdata_file)
# Set some ranges for the plot
<- list(A = c(-3.3, 3.3), B = c(-4.4, 4.4))
rngs
$spline_contours <-
outputrenderImage({
<- predicted_values[predicted_values$deg_free == input$deg_free,]
preds
<-
p ggplot(preds, aes(A, B)) +
# Plot the validation set
geom_point(
data = sim_val,
aes(col = class, pch = class),
alpha = 1 / 2,
cex = 3
+
) # Show the class boundary
geom_contour(
aes(z = .pred_one),
breaks = 1 / 2,
linewidth = 3 / 2,
col = "black"
+
) # Formatting
lims(x = rngs$A, y = rngs$B) +
theme_bw() +
theme(legend.position = "top")
3<-
file ::capturePlot(
htmltoolsprint(p),
tempfile(fileext = ".svg"),
::svg,
grDeviceswidth = 4,
height = 4
)list(src = file)
}, 4deleteFile = TRUE)
}
<- shinyApp(ui = ui, server = server) app
- 1
- This block sets up URLs pointing to the GitHub raw objects.
- 2
- Both data sets are downloaded to a temporary file and loaded into the session.
- 3
- Code allowing us to save the visualization as an SVG image. This is an aesthetic choice and unrelated to the point of this repo.
- 4
- Clean up the SVG file passed between the server and UI.
2.5 The results
Our beautiful shiny
app!
You can reference Figure 2.1 in the usual way (via @fig-shiny-spline
).
2.6 Making the shiny app a figure
As previously mentioned, following the usual convention of using a fig-
prefix for a chunk will not make the shiny
app a figure. However, the 1.4 release of Quarto (pre-release version as of this writing) has a new feature to make anything a specific type of content (such as a figure).
We use the :::
syntax to declare the figure and any critical options. In my case above, this was
::: {#fig-shiny-spline}
::: {.figure-content}
```{shinylive-r}
#| label: fig-shiny-spline
#| viewerHeight: 500
#| standalone: true
<-- my shiny app code here-->
app <- shinyApp(ui = ui, server = server)
```
:::
A visualization of the class boundary for different numbers of degrees of `A` and `B`.
freedom for natural spline features in
:::
You probably don’t have to use the same chunk name ({#fig-shiny-spline}
) in two places; this is the more important place to specify it. I like having them the same.