library(tidyverse)
library(glue)
# Make some plots
p1 <- ggplot(mpg, aes(x = cyl, y = hwy, color = drv)) +
geom_point()
p2 <- ggplot(mpg, aes(x = hwy, fill = drv)) +
geom_density()
p3 <- ggplot(mpg, aes(x = displ, y = hwy, color = drv)) +
geom_point()
# I find it easiest to work with all these things in a data frame, but it's not necessary
output_stuff <- tribble(
~panel_title, ~plot,
"Plot 1", p1,
"Plot 2", p2,
"Plot 3", p3
)Panel tabset from list of plots
The plots are all in this output_stuff$plot list:
output_stuff$plot[[3]]
For a tabset, the markdown needs to look like this:
::: {.panel-tabset}
### Title
```{r}
output_stuff$plot[[1]]
```
### Another title
```{r}
output_stuff$plot[[2]]
```
:::So we can build each of these panels in the data frame:
build_panel <- function(panel_title, plot_index) {
output <- glue("
### <<panel_title>>
```{r}
#| echo: false
output_stuff$plot[[<<plot_index>>]]
```", .open = "<<", .close = ">>")
# ↑ It's best to override glue's {} delimiters because of the ```{r} chunk
output
}
output_with_markdown <- output_stuff |>
mutate(row = row_number()) |>
# We could use map2_chr(), but I like using pmap() just in case I need to
# expand it beyond 2 things
mutate(markdown = pmap_chr(
lst(panel_title, row),
\(panel_title, row) build_panel(panel_title, plot_index = row)
))Now we have a markdown panel for each plot:
cat(output_with_markdown$markdown[[1]])### Plot 1
```{r}
#| echo: false
output_stuff$plot[[1]]
```
# We can collapse all these panels into one big character object, wrapped in Quarto's special .panel-tabset div
final_markdown <- paste0(
"::: {.panel-tabset}\n\n",
paste0(output_with_markdown$markdown, "\n", collapse = "\n"),
"\n:::"
)Check it out!
cat(final_markdown)::: {.panel-tabset}
### Plot 1
```{r}
#| echo: false
output_stuff$plot[[1]]
```
### Plot 2
```{r}
#| echo: false
output_stuff$plot[[2]]
```
### Plot 3
```{r}
#| echo: false
output_stuff$plot[[3]]
```
:::
However, this won’t render/knit properly, even if we add results="asis" to the chunk options.
But we can feed it to knitr::knit() in an inline chunk:
# This, but in an inline chunk
knitr::knit(text = final_markdown)

