library(tidyverse)
library(glue)
# Make some plots
<- ggplot(mpg, aes(x = cyl, y = hwy, color = drv)) +
p1 geom_point()
<- ggplot(mpg, aes(x = hwy, fill = drv)) +
p2 geom_density()
<- ggplot(mpg, aes(x = displ, y = hwy, color = drv)) +
p3 geom_point()
# I find it easiest to work with all these things in a data frame, but it's not necessary
<- tribble(
output_stuff ~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:
$plot[[3]] output_stuff
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:
<- function(panel_title, plot_index) {
build_panel <- glue("
output ### <<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_stuff |>
output_with_markdown 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),
build_panel(panel_title, plot_index = row)
\(panel_title, 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
<- paste0(
final_markdown "::: {.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
::knit(text = final_markdown) knitr