0

I have a code chunk in an R Markdown file, that generates multiple ggplots in a for loop. The chunk (pseudo-code) is called like so:

```{r print_data, results='asis'}
print.all.results()
```

Inside the print.all.results(), the ggplots are generated and printed using standard print(plot) (see below). This works without any problems (HTML as well as PDF).

For the PDF outputs, I would now like to switch to landscape mode using \usepackage{pdflscape} (already added to the preamble).

I then tried to switch to the landscape environment in the R code within the chunk. Based on this question and this question, I added the following lines within the print.all.results() function:

cat("\\begin{landscape}")

for (index in vector) {
    plot <- generateplot()
    print(plot)
}

cat("\\end{landscape}")

However, as soon as I do this, the knitting of the document fails. In the intermediary .tex file, the graphics are not called via \includegraphics anymore but rather, they are linked via the markdown call to them (which of course fails in a tex compile):

\begin{landscape}

![](rmddocument_files/figure-latex/print_data-1.pdf)<!-- --> 

![](rmddocument_files/figure-latex/print_data-2.pdf)<!-- --> 

![](rmddocument_files/figure-latex/print_data-3.pdf)<!-- -->

\end{landscape}

I have also tried multiple variations using pander but did not find a working solution.

I am now confused why a) the inclusion of the environment suddenly changes the behavior of the print for the plot and b) something comparable seems to work in example 2.

Is this a bug? Could this be a problem with my build pipeline? What could be a solution?

NB: I can't generate the latex code in the .rmd - it has to happen within the code chunk.

An MWE would be this (easiest run trough Knit Button in R Studio; the .tex files and pdfs from the plot are generated in the same folder):

---
title: "Landscape Problem"
author: "Dom42"
date: "`r Sys.Date()`"
output: 
  pdf_document: 
    extra_dependencies: pdflscape
    keep_tex: yes
---

```{r function}
print.plots.landscape <- function() {
  cat("\\begin{landscape}")
  
  for (i in 1:3) {
    temp.plot <- plot(hist(mtcars[,i]))
    
    print(temp.plot)
  }
  
  cat("\\end{landscape}")
}
```

```{r call, results='asis'}
print.plots.landscape()
```

This Example produces a .tex that contains

\begin{landscape}![](landscape-example_files/figure-latex/call-1.pdf)<!-- --> NULL
![](landscape-example_files/figure-latex/call-2.pdf)<!-- --> NULL
![](landscape-example_files/figure-latex/call-3.pdf)<!-- --> NULL
\end{landscape}

However, what should actually come out of it (works, if uncommenting the cats in the for-loop):

\includegraphics{landscape-example_files/figure-latex/call-1.pdf} NULL
\includegraphics{landscape-example_files/figure-latex/call-2.pdf} NULL
\includegraphics{landscape-example_files/figure-latex/call-3.pdf} NULL

If these three calls would now be enclosed in a landscape environment, I would be happy and my problem would be solved.

shafee
  • 15,566
  • 3
  • 19
  • 47
Dom42
  • 147
  • 11
  • It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Jan 03 '23 at 16:28
  • @MrFlick, indeed you are correct. I'm sorry, but I did not have the time earlier to add it. A base snippet is now added. I think input/output and what the error is, is also clear from the question. If I have the time later on, I can also add that. – Dom42 Jan 03 '23 at 16:51

1 Answers1

3

The reason you are getting the simple markdown syntax for image insertion after including the landscape environment is because pandoc (the underlying document converter of r-markdown) does not parse the content of latex environments.

To add more details, when you click the knit button of Rstudio, the {knitr} package generates a markdown file containing the markdown syntax for image which as below,

\begin{landscape}
![](landscape-example_files/figure-latex/call-1.pdf)<!-- --> NULL
![](landscape-example_files/figure-latex/call-2.pdf)<!-- --> NULL
![](landscape-example_files/figure-latex/call-3.pdf)<!-- --> NULL
\end{landscape}

And then pandoc is supposed to convert the markdown syntax into latex commands (i.e. \includegraphics), But since pandoc sees the latex environment \begin{landscape}, it doesn't do the conversion and keeps them as is.

So to solve it, we can use the \landscape ... \endlandscape command instead of latex environment (thanks to the informative comment by @samcarter_is_at_topanswers.xyz)

---
title: "Landscape Problem"
author: "Dom42"
date: "`r Sys.Date()`"
output: 
  pdf_document: 
    keep_tex: yes
header-includes:
    - \usepackage{pdflscape}
---

```{r function}
print.plots.landscape <- function() {
  cat("\\landscape\n")
  
  for (i in 1:3) {
    temp.plot <- plot(hist(mtcars[,i]))
    
    print(temp.plot)
  }
  
  cat("\n\\endlandscape\n")
}
```

```{r call, results='asis'}
print.plots.landscape()
```
shafee
  • 15,566
  • 3
  • 19
  • 47
  • 2
    You don't need to define new commands, you can directly use the underlaying commands with which the environment is defined `\landscape ... \endlandscape` – samcarter_is_at_topanswers.xyz Jan 05 '23 at 11:11
  • Great solution! This works! Kudos for tracking down that Google Groups discussion from ten years ago. I was suspecting something like this but did not find any mention in the documentation for either rmarkdown or pandoc (but obviously I was just not looking enough ;)) – Dom42 Jan 05 '23 at 12:01