Search code examples
rlatexr-markdownknitrpander

Landscape environment in R Code Chunk in R Markdown breaks plot print


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.


Solution

  • 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()
    ```