Show PNG images consecutively with loop in R Markdown chunk (HTML)

Can one use an R Markdown chunk loop to show multiple graphics files (e.g., PNG) consecutively (one above the other) in HTML output? This loop would identify the files in a vector, such as via list.files().

I have experimented with uses of writeLines("\n"), cat('\r\n\r\n'), knit_expand() [per this SO to no avail].

This R Markdown code (formatted below but link is .Rmd) is a reproducible example with an attempt using writeLines("\n") and cat('\r\n\r\n'). Please note this copies 5 R logo PNG (only 12kb) file copies into your working directory.


title: "Consecutive PNG Loop Attempt"
author: "Rick Pack"
date: "11/20/2019"
output: html_document

knitr::opts_chunk$set(echo = TRUE)

Copy a PNG file as multiple files

for (q in 1:5) {
 file.copy(list.files(system.file("img", package = "png"), 
                      full.names = TRUE),
           getwd())
 file.rename("Rlogo.png", paste0("Rlogo_",q,".png"))
}

Only one R logo shown instead of the five available

library(png)
# Providing the folder so you can delete the png files
# created above
print(getwd())
 all_img <- list.files(full.names = TRUE)[grepl(
     "Rlogo", list.files())]
 for (j in 1:length(all_img)) {  
 grid::grid.raster(readPNG(all_img[j]))
writeLines("\n")
cat('\r\n\r\n')  
cat("\n\n\\pagebreak\n")
 }

Showing only one PNG file appeared

1 Like

Hi @rick_pack2,

I have a couple approaches in mind. Can you confirm what you are hoping to achieve? You want to just loop over a vector of image files and make sure they all show up in the rendered document?

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

What about something like this:

---
output: html_document
---

```{r}
read_and_plot <- function(path) {
  x <- png::readPNG(path)
  plot(x)
}
```

```{r out.width="50%"}
# replace path with path to your image files
purrr::walk(fs::dir_ls('path/to/pngs/here', 
                       type = 'file', glob = '*.png'), 
            read_and_plot)
```
1 Like

Yes and thank you, @mattwarkentin, I want to loop over a vector of image files and show all of them in the rendered document.

Rather than using a loop, this Stack Overflow response caused me to discover can point include_graphics() to a vector containing the full path to graphics files a la:
knitr::include_graphics(all_img)

3 Likes

Thank you, Matt, but that did not work. The plot function prints unexpected output and when I printed the readPNG() output, I still have the problem of each image file replacing the prior one.

Great, glad you got it all working. The walk() code worked on my end, not sure why it didn't for you. But knitr::include_graphics() is a simpler solution.