3

In R, I have prepared multiple ggplot2 figures, that are saved to variables like this:

flashplot <- ggplot(flash, aes(x=flash$Year, y=flash$Proc)) 
+ stat_smooth(method="lm", formula = "flash$Proc ~ poly(flash$Year, 2, raw=TRUE)", n=14, level=0.9) 
+ geom_point(shape=19) + ylab("Percentage of total existing versions") 
+ xlab("Years of Existence") + scale_x_continuous(breaks = c(0,2,4,6,8,10,12,14,16,18,20))

plotting a single figure works as expected, but I want to plot 4 figures (2 by 2) using multiplot, as described in the R cookbook.

As I got an error, I tried the example from the cookbook, which I thould would work, but it gave me the same error:

> multiplot(p1, p2, p3, p4, cols=2)
Error in UseMethod("getModelInfo", model) : 
  no applicable method for 'getModelInfo' applied to an object of class "c('gg', 'ggplot')"

I am using R 2.15.2 under Windows 7, and the newest packages of ggplot2 and coefplot:

> sessionInfo()
R version 2.15.2 (2012-10-26)
Platform: i386-w64-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=German_Austria.1252  LC_CTYPE=German_Austria.1252   
[3] LC_MONETARY=German_Austria.1252 LC_NUMERIC=C                   
[5] LC_TIME=German_Austria.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] coefplot_1.1.8 ggplot2_0.9.3 

loaded via a namespace (and not attached):
 [1] colorspace_1.2-0   dichromat_1.2-4    digest_0.6.0       grid_2.15.2       
 [5] gtable_0.1.2       labeling_0.1       MASS_7.3-22        munsell_0.4       
 [9] plyr_1.8           proto_0.3-9.2      RColorBrewer_1.0-5 reshape2_1.2.2    
[13] scales_0.2.3       stringr_0.6.2      useful_1.1.6      

any hints to help me solving my problem would be highly appreciated. Am I missing something? I already searched the web, but found nothing helpful

-- As requested, here is the example data:

library(ggplot2)

# This example uses the ChickWeight dataset, which comes with ggplot2
# First plot
p1 <- 
    ggplot(ChickWeight, aes(x=Time, y=weight, colour=Diet, group=Chick)) +
    geom_line() +
    ggtitle("Growth curve for individual chicks")

# Second plot
p2 <- 
    ggplot(ChickWeight, aes(x=Time, y=weight, colour=Diet)) +
    geom_point(alpha=.3) +
    geom_smooth(alpha=.2, size=1) +
    ggtitle("Fitted growth curve per diet")

# Third plot
p3 <- 
    ggplot(subset(ChickWeight, Time==21), aes(x=weight, colour=Diet)) +
    geom_density() +
    ggtitle("Final weight, by diet")

# Fourth plot
p4 <- 
    ggplot(subset(ChickWeight, Time==21), aes(x=weight, fill=Diet)) +
    geom_histogram(colour="black", binwidth=50) +
    facet_grid(Diet ~ .) +
    ggtitle("Final weight, by diet") +
    theme(legend.position="none")        # No legend (redundant in this graph) 

multiplot(p1, p2, p3, p4, cols=2)
Stefan S
  • 650
  • 2
  • 10
  • 23
  • Can you supply the data or create fake data so that we have a reproducible example that we can copy, paste and experiment with? – SlowLearner Dec 10 '12 at 00:22
  • As the example from the R cookbook doesn't work, I think it's not a problem with my prepared graphs. I have copied the data from the cookbook to the bottom of my question. – Stefan S Dec 10 '12 at 07:57
  • Problem solved, see my answer below. Thank you for your efforts. – Stefan S Dec 10 '12 at 08:07
  • 1
    You can use `gridExtra` package for efficiently laying out plots (e.g. http://stackoverflow.com/questions/11606441/ggplot2-gridextra-how-to-ensure-geom-bar-in-different-size-plot-grobs-result, http://stackoverflow.com/questions/5226807/multiple-graphs-in-one-canvas-using-ggplot2). – Roman Luštrik Dec 10 '12 at 10:15
  • Thank you for this hint, that seems to be a very effectife way to handle multiple figures – Stefan S Dec 10 '12 at 18:52

2 Answers2

7

There is a much easier option to do the same by using an inbuilt function called grid.arrange(). You need to install the package called gridExtra to use it:

grid.arrange(p1,p2,p3,p4, ncol = 2, main = "Main title")

Reference

honk
  • 9,137
  • 11
  • 75
  • 83
1

Problem solved. I thought I should uses the predefined multiplot function from the coefplot package, but in fact I had to use the custom function, that has been defined on the R cookbook page.

multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
  require(grid)

  # Make a list from the ... arguments and plotlist
  plots <- c(list(...), plotlist)

  numPlots = length(plots)

  # If layout is NULL, then use 'cols' to determine layout
  if (is.null(layout)) {
    # Make the panel
    # ncol: Number of columns of plots
    # nrow: Number of rows needed, calculated from # of cols
    layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
                    ncol = cols, nrow = ceiling(numPlots/cols))
  }

 if (numPlots==1) {
    print(plots[[1]])

  } else {
    # Set up the page
    grid.newpage()
    pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))

    # Make each plot, in the correct location
    for (i in 1:numPlots) {
      # Get the i,j matrix positions of the regions that contain this subplot
      matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))

      print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
                                      layout.pos.col = matchidx$col))
    }
  }
}
Stefan S
  • 650
  • 2
  • 10
  • 23
  • 1
    I was about to say that it works for me if I use `multiplot` as defined in the R Cookbook. All's well that ends well. – SlowLearner Dec 10 '12 at 08:20