1

I want to print list of graphs throw .Rnw. Wonder how to accomplish the task.

\documentclass{article}


\begin{document}
\SweaveOpts{concordance=TRUE}

\begin{figure}[H]
<< label = Plot >>=
library(tidyverse)
Ys <- c("disp", "hp", "drat", "wt", "qsec")

Plots <- 
  Ys %>% 
  map(function(y)
    ggplot(data = mtcars, mapping = aes(x = mpg, y = y)) +
      geom_point(aes_string(y = y))
  )

print(Plots)
@
\end{figure}


\end{document}
MYaseen208
  • 22,666
  • 37
  • 165
  • 309
  • Are you using knitr (not Sweave)? If so, knitr [can save the graphs as files too](https://stackoverflow.com/questions/27992239/knitr-include-figures-in-report-and-output-figures-to-separate-files). – wibeasley Jun 23 '18 at 06:13
  • I'm using knitr. – MYaseen208 Jun 23 '18 at 06:18

3 Answers3

3

You can use one of the variations on purrr::walk to silently map over the list of plots and save them with ggsave. walk2 maps over two lists, or iwalk maps over a list and its names. iwalk is really simple if you give the plot list names; the way I did it here is a little awkward, but in the wild, such as when plotting from a data frame that's been split, or with a vector that already has names, it could be different.

aes_string is used for creating aes calls programmatically, but it's being deprecated in favor of tidy eval; one example of this is in the aes docs, but I also was reminded of how to do it by this answer.

I first name the vector, with its own values as its names. Then I map over it and apply a function that takes a string y and creates a symbol of it using rlang::sym. This allows me to use tidy eval to create a bare column name with !!y_sum.

# https://stackoverflow.com/a/50726130/5325862
Plots <- Ys %>%
  setNames(., nm = .) %>%
  map(function(y) {
    y_sym <- rlang::sym(y)

    ggplot(data = mtcars, aes(x = mpg, y = !!y_sym)) +
      geom_point()
  })

Example of one plot in the list, which can be accessed by name:

Plots$hp

Then to save the plots, iwalk over using the names to create filenames. You can add additional parameters to ggsave, such as dimensions and resolution.

Plots %>%
  iwalk(~ggsave(filename = sprintf("%s_vs_mpg.png", .y), plot = .x))
#> Saving 7 x 5 in image
#> Saving 7 x 5 in image
#> Saving 7 x 5 in image
#> Saving 7 x 5 in image
#> Saving 7 x 5 in image

You can do everything in one step if you need: map along to make plots and save in a single function. I went with the approach of saving the plots to a list, since that's what you did in the question, and that allows you to pull up individual plots in your document, rather than only saving them as files.

camille
  • 16,432
  • 18
  • 38
  • 60
  • Thanks @camille for your answer. I'm still not able to get it correctly. Please see my edits and suggest any solution. Thanks – MYaseen208 Jul 28 '18 at 14:53
  • What exactly doesn't work? And what's the reason for not using Rmarkdown, which should be able to do this more simply? – camille Jul 28 '18 at 15:05
1

This will create the five pngs in the working directory, (which is the location of the Rnw file, unless you've modified it with something like opts_knit$set(root.dir='../../')).

Ys %>% 
  purrr::iwalk(
    ~ggplot(mtcars, aes_string(x = "mpg", y = .x)) +
        geom_point() +
        ggsave(filename = .y, device = "png")
  )
wibeasley
  • 5,000
  • 3
  • 34
  • 62
  • Thanks @wibeasley for your answer. I'm still not able to get it correctly. Please see my edits and suggest any solution. Thanks – MYaseen208 Jul 28 '18 at 14:53
1

try:

\documentclass{article}

\begin{document}
\SweaveOpts{concordance=TRUE}

<< label = Plot >>=
library(tidyverse)
Ys <- c("disp", "hp", "drat", "wt", "qsec")

Plots <- 
  Ys %>% 
  map(function(y)
    ggplot(data = mtcars, mapping = aes(x = mpg, y = y)) +
      geom_point(aes_string(y = y))
  )

@

<<results=tex,echo=FALSE, >>=

for(i in 1:length(Plots)){
file=paste("myfile", i, ".png", sep="")
png(file, res = 80)
print(Plots[[i]])
dev.off()
cat(  "\\begin{figure}\n\\includegraphics{", file, "}\n\n\\end{figure}\n", sep="")
}
@

\end{document}

enter image description here

It is really advisable to switch to knitr

Putting 4 plots in one

\documentclass{article}


\begin{document}
\SweaveOpts{concordance=TRUE}
\begin{figure}

<< label = Plot , fig=TRUE,results=hide>>=
library(tidyverse)
library(gridExtra)
Ys <- c("disp", "hp", "drat", "wt", "qsec")

plotLlist<-list()
for (i in 1:length(Ys)) {
  plotLlist[[i]]<- ggplot(data = mtcars,  aes_string(x = "mpg", y = Ys[i])) +
  geom_point(aes_string(y = Ys[i]))

}
print(grid.arrange(grobs =plotLlist[1:4], nrow = 2))

@
\end{figure}


\end{document}

enter image description here

Community
  • 1
  • 1
Iman
  • 2,224
  • 15
  • 35