creating a vector with plots

I want to create a series of plots, and then I plan to use ggarrange to put them in a single picture.
I have a code which works but assigning plots to a vector corrupts the plots except the last one.
What should be changed for this to work?

In the example below, print(pp) prints correctly all plots, however Plots contains corrupted plots (last plot is somehow added to previous ones)

library(tidyverse)

mtcars$names <- rownames(mtcars)

Plots <- vector(length=32,"list")

for (i in 1:32) {

x <- mtcars[[i,12]]
y <- mtcars[[i,3]]

pp <- ggplot() + 
  aes(x=x , y=y)+
  geom_point()+
  labs(title="",x="",y="")+
  geom_text(aes(label=round(y,2)),hjust=-0.2, vjust=-0.2, color="black")+
  theme_bw()+
  geom_hline(yintercept=0, linetype="dashed", color = "red", size= 0.5)+
  annotate("text",x=min(x),y= 0, hjust = 2, vjust = -0.2, label = "zero line", color = "red")

print(pp)   #works fine, but I need to collect all plots to use them further with ggarrange()
Plots[[i]] <- pp
}

Plots  #has corrupted plots

Hi,

The code might be easier if you use the lapply instead of a loop

library(ggplot2)
library(gridExtra)

mtcars$names <- rownames(mtcars)

Plots = lapply(1:32, function(i){
  x <- mtcars[[i,12]]
  y <- mtcars[[i,3]]
  
  ggplot() + 
    aes(x=x , y=y)+
    geom_point()+
    labs(title="",x="",y="")+
    geom_text(aes(label=round(y,2)),hjust=-0.2, vjust=-0.2, color="black")+
    theme_bw()+
    geom_hline(yintercept=0, linetype="dashed", color = "red", size= 0.5)+
    annotate("text",x=min(x),y= 0, hjust = 2, vjust = -0.2, label = "zero line", color = "red")
})

#Show first plot
Plots[1]
#> [[1]]


#Show first 4 plots
do.call("grid.arrange", Plots[1:4])

Created on 2020-08-05 by the reprex package (v0.3.0)

PJ

Hello and thank you!

Did not know you could use lapply like this, that's good to know (I thought of apply but did not get it working properly).
Also, it's first time I see "do.call" (I'm just beginning with R). Tried to use grid.arrange alone (as I needed to use it with ggsave instead of plotting on the screen) and it did not work with Plots[1:4] as its sole argument.
Again something to learn. Thanks :slight_smile:

1 Like

HI,

Glad to hear I was able to help.
The do.call function is rarely needed, and I had to look it up myself again as well since it's been a long time since I used grid.arrange. What it does is it calls a function (in this case grid arrange) and then supplies the arguments to that function as a list you can define (Plots list here). If you just supply the list itself directly to the function, it will see the whole list as one argument, and not as multiple.

Hope this helps,
PJ

Thanks for clearing this up for me and thanks for help.
Best regards!

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