Last active
October 30, 2024 15:26
-
-
Save andrewheiss/88252d55878ab01166db7e7ee605f0a6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
title: Panel tabset from list of plots | |
--- | |
```{r} | |
#| warning: false | |
#| message: false | |
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 | |
) | |
``` | |
The plots are all in this `output_stuff$plot` list: | |
```{r} | |
output_stuff$plot[[3]] | |
``` | |
For a tabset, the markdown needs to look like this: | |
````default | |
::: {.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: | |
```{r} | |
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: | |
```{r} | |
cat(output_with_markdown$markdown[[1]]) | |
``` | |
```{r} | |
# 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! | |
```{r} | |
cat(final_markdown) | |
``` | |
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: | |
```r | |
# This, but in an inline chunk | |
knitr::knit(text = final_markdown) | |
``` | |
`r knitr::knit(text = final_markdown)` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment