2

Currently, I am writing a Quarto Markdown document with an HTML output. In this document I want to show several plots. Each plot should be within an own section in order to facilitate navigation. As I want to reduce boilerplate I create the plots dynamically. Now, the section headers appear one after another while the plots all appear at the end of the section.

Here is a reproducible example:

---
title: "Untitled"
format: html
editor: visual
---

## Quarto

```{r}
#| label: fig-attr-in-time
#| fig-cap: "Attribute in time"
#| results: "asis"
library(dplyr)
library(ggplot2)
library(purrr)
data_files = c(
  "test1",
  "test2",
  "test3"
)
set.seed(176)
test1 = data.frame(year = 1991:2010, ratio = runif(20, 0, 1))
test2 = data.frame(year = 1991:2010, ratio = runif(20, 0, 1))
test3 = data.frame(year = 1991:2010, ratio = runif(20, 0, 1))

print_attr_plots = function(data) {
  cat('\n\n### ', data, '\n')
  data_tmp = get(data)
  p = ggplot(data_tmp, aes(x = year, y = ratio)) + geom_bar(stat = "identity", color =     "black", fill = "white") + ylab("Ratio") + xlab("Year") + theme_grey(base_size = 10)
  print(p)
}
pwalk(list(data_files), print_attr_plots)
```

This is my result: enter image description here

Instead, I want the section headers and plots to alternate. This code actually works in R-Markdown but strangely it does not in Quarto. Please help.

shafee
  • 15,566
  • 3
  • 19
  • 47
Irazall
  • 117
  • 9
  • 2
    It's likely due to the `label` and `fig-cap`. Removing them makes it work – AdroMine May 31 '23 at 16:19
  • @AdroMine Thanks! This worked. This is quite an odd behaviour. I tested it as well and I can save at least the label if I put it next to "r" in the curly brackets. If you write it down as a solution, I am going to accept it. – Irazall May 31 '23 at 16:46

1 Answers1

3

The reason of Quarto putting the figures together is because of that special fig- prefixed label and not because you are using fig-cap. Your intended approach would work if you had used either a simple label (like label: test, i.e. not fig- prefixed) or no label at all and fig-cap.

So the following works as intended (almost!!!),

Note that, I have used a list structure in fig-cap so that three plots have different captions.

---
title: "Untitled"
format: html
---

## Quarto

```{r}
#| fig-cap: 
#|    - "Attribute in time in test1"
#|    - "Attribute in time in test2"
#|    - "Attribute in time in test3"
#| results: "asis"
#| message: false
#| echo: false

library(dplyr)
library(ggplot2)
library(purrr)
data_files = c(
  "test1",
  "test2",
  "test3"
)
set.seed(176)
test1 = data.frame(year = 1991:2010, ratio = runif(20, 0, 1))
test2 = data.frame(year = 1991:2010, ratio = runif(20, 0, 1))
test3 = data.frame(year = 1991:2010, ratio = runif(20, 0, 1))

print_attr_plots = function(data) {
  cat('\n\n### ', data, '\n')
  data_tmp = get(data)
  p = ggplot(data_tmp, aes(x = year, y = ratio)) + 
      geom_bar(stat = "identity", color = "black", fill = "white") + 
      ylab("Ratio") + xlab("Year") + 
      theme_grey(base_size = 10)
  
  print(p)
}

walk(data_files, print_attr_plots)
```

rendered output

But the above approach is not quite enough (in my opinion). Because if you look at the output, you would see there are no Figure prefix in the captions and since you are not using a label, you can not refer to these figures.

So to solve this completely, you may want to use `Figure Divs,

---
title: "Untitled"
format: html
keep-md: true
---

## Quarto

```{r}
#| results: "asis"
#| message: false

library(dplyr)
library(ggplot2)
library(purrr)
data_files = c(
  "test1",
  "test2",
  "test3"
)
set.seed(176)
test1 = data.frame(year = 1991:2010, ratio = runif(20, 0, 1))
test2 = data.frame(year = 1991:2010, ratio = runif(20, 0, 1))
test3 = data.frame(year = 1991:2010, ratio = runif(20, 0, 1))

print_attr_plots = function(data) {
  cat('\n\n### ', data, '\n')
  data_tmp = get(data)
  p = ggplot(data_tmp, aes(x = year, y = ratio)) + geom_bar(stat = "identity", color =     "black", fill = "white") + ylab("Ratio") + xlab("Year") + theme_grey(base_size = 10)
  
  div_label <- paste0("#fig-", data)
  cat("\n::: {", div_label, "}\n", sep="")
  print(p)
  cat("\n\nAttribute in time in ", data, "\n", sep="")
  cat("\n:::\n")
}

walk(data_files, print_attr_plots)
```

check the plots @fig-test1, @fig-test2, @fig-test3

Here a separate Figure-Divb with id (which you can use in cross-referencing) and a caption is being created for each figure. Check out the linked documentation to know details about Figure-Divs.

rendered output

shafee
  • 15,566
  • 3
  • 19
  • 47