37

as a new ggplot2 user, I am a bit lost with the amount of possibilities, and struggle to find on the net a simple answer to what I consider a simple problem.

I would like to display multiple plots from ggplot2 on a same sheet, BUT knowing that these plots come from a for loop.

Following example does not compile, it is only to illustrate :

for(i in c(1:n)){                                   
  for(j in c(1:m)){
    ..........  # some data production
    p <- ggplot(df.all) + geom_bar(aes_string(x=class.names[i],fill=var.names[j])
}}

Here, p is overwritten, but I would like to have instead a matrix or a list in which I can put all the p as they are produced, then a simple function like

display_in_a_grid(list_of_ggplot_plots)

But as far as I tried, I was not able to make a list of matrix of plot, neither to find a function that takes only one argument for input.

About things I have had a look at :

"arrangeGrob" from package gridExtra doesn't work because it requires an explicit name for each plot (e.g.: p1,p2,p3,...) like in http://code.google.com/p/gridextra/wiki/arrangeGrob

"facet" method of ggplot2 is not adapted to the organization of my data set (or the contrary :p )

Would you have a simple way to manage this ?

Thank you,

François

Richie Cotton
  • 118,240
  • 47
  • 247
  • 360
fstevens
  • 1,287
  • 1
  • 17
  • 28
  • 1
    You are on the right track. If you are drawing lots of bar charts of different cases, then a single plot with multiple facets is the standard approach. It will probably be best to manipulate your into a suitable form to achieve this, rather than finding a hack for multiple plots. – Richie Cotton Feb 16 '12 at 17:23
  • Thanks. I agree this is certainly the most reasonnable solution. The thing is that for each separate plot, I also want to make some data treatment (aggregate small classes and complete chi squared test) and display p-value as induvidual plot title. So that is certainly possible to include in facet method, but I think I will have to use a p loop anyway at some point. – fstevens Feb 17 '12 at 09:05
  • You can use `geom_text` to annotate each facet with p values. – Richie Cotton Feb 17 '12 at 09:34
  • See the answer on this post https://stackoverflow.com/a/45185980/18143306 – Melanie Baker Mar 22 '22 at 11:33

2 Answers2

63

I would be inclined to agree with Richie, but if you want to arrange them yourself:

library(gridExtra)
library(ggplot2)
p <- list()
for(i in 1:4){
  p[[i]] <- qplot(1:10,10:1,main=i)
}
do.call(grid.arrange,p)

take a look at the examples at the end of ?arrangeGrob for ways to eliminate the for loop altogether:

plots = lapply(1:5, function(.x) qplot(1:10,rnorm(10),main=paste("plot",.x)))
require(gridExtra)
do.call(grid.arrange,  plots)
Justin
  • 42,475
  • 9
  • 93
  • 111
  • 1
    Thanks. A lot clearer that information I read in help manuals, and an illustration of do.call function that I have never used. I will use this solution if I fail using facets. – fstevens Feb 17 '12 at 09:19
  • 4
    Your first example produces identical plots in the case of "qplot(c(1:10), c(10:1) + i, main = i)'" – Stepan S. Sushko Feb 02 '17 at 12:29
  • 3
    How would I use this to add grid.arrange parameters such as ncol, nrow, heights, widths, etc. – CrashOverride Mar 23 '18 at 02:18
  • https://stackoverflow.com/questions/18262064/specify-function-parameters-in-do-call – aaaaa Sep 04 '18 at 09:25
-1

This is my solution. Tiny change in the ggplot function with the mapping parameter to aes_string.

library(gridExtra)
library(ggplot2)
p <- list()
for(i in 1:4){
p[[i]] <- ggplot(data=df,aes_string(x=df$x,y=df$y) +geom_bar(aes_string(x=class.names[i],fill=var.names[j])
}
do.call(grid.arrange,p)

Hope this helps!

jiang ziqi
  • 47
  • 1
  • 1
  • 5