Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a vector of ggplot objects to grid.arrange function?

Perhaps the problem has been asked and solved, but the solution didn't work for me. I wrote a function able to create ggplot objects and return them in a vector. The following is the code inside the function, vars is a vector of column names of my data d.

plotting <- function(d){
    P <- numeric(0)
    vars <- names(d)[!names(d)%in%c('channel','label')]
    for (var in vars){
        p <- ggplot(d, aes(x=channel,y=var)) + 
             geom_boxplot(aes(fill=label)) + ggtitle(var)
        P <- c(P,p)
    }
    return(list(plots=P, num=length(vars)))
}

What I want to do is to use the above function to return a concatenated lists P consisting of several ggplots objects as following which is the 'manual' version working fine:

p1 <- ggplot()+ ...
p2 <- ggplot()+ ...
p3 <- ggplot()+ ...
pdf('...')
grid.arrange(p1, p2, p3, nrow = 3)
dev.off()

The purpose of returning num is for latter usage in layout arg. of grid.arrange function. I have PLOTS as returning variable:

PLOTS <- plotting(d)
pdf('...')
grid.arrange(PLOTS$plots, PLOTS$num)
dev.off()

and I got error:

Error in arrangeGrob(..., as.table = as.table, clip = clip, main = main,  :
input must be grobs!

So I tried the solution in Passing a vector to grid.arrange as a list of arguments.

do.call(grid.arrange, c(PLOTS$plots, nrow = PLOTS$num))

but still get the same error. Any comment would be appreciated.

Edit: made problem description clearer, and paste the reproducible data d below:

structure(list(percent = c(0.0962463533974437, 0.129409967469436,
0.0150265653130588, 0.00299276735619027, 0.0108596845008112,
0.00407417010800106), songs = c(0.231617443342384, 0.430320945945946,
0.109264389042782, 0.282109656611649, 0.0288753799392097, 0.041635687732342
), label = c("1", "1", "1", "1", "1", "1"), channel = c("2",
"2", "2", "2", "2", "2")), .Names = c("percent", "songs", "label",
"channel"), row.names = c(NA, 6L), class = "data.frame")

Please input d as argument to plotting and proceed to PLOTS$plots to help me for debugging, thank you!

like image 781
Francis Avatar asked Jan 09 '15 10:01

Francis


People also ask

What are the plots in ggplot2?

The plots can be either ggplot2 plot objects or arbitrary gtables. (optional) list of plots to display. (optional) number of columns in the plot grid.

How to arrange multiple ggplots on the same page?

Arrange multiple ggplots on the same page. Wrapper around plot_grid (). Can arrange multiple ggplots over multiple pages, compared to the standard plot_grid (). Can also create a common unique legend for multiple plots. ... list of plots to be arranged into the grid. The plots can be either ggplot2 plot objects or arbitrary gtables.

How do I change the color of the grid in ggplot2?

By default, ggplot2 creates a major and a minor white grid as shown in the following figure. The grid aesthetics can be set with the panel.grid component of the theme function. Customize the color, line width and line type with the arguments of the element_line function.

What is wrapper around plot_grid () in ggplot2?

Wrapper around plot_grid (). Can arrange multiple ggplots over multiple pages, compared to the standard plot_grid (). Can also create a common unique legend for multiple plots. ... list of plots to be arranged into the grid. The plots can be either ggplot2 plot objects or arbitrary gtables.


1 Answers

Your plotting function has a few problems. First you need to initialize P as a list. Second, you need to use aes_string instead of aes, if you want to use the character input var. And then you have to use list(p), to keep the ggplot object intact.

plotting <- function(d){
  P <- list()
  vars <- names(d)[!names(d)%in%c('channel','label')]
  for (var in vars){
    p <- ggplot(d, aes_string(x='channel', y=var)) + 
      geom_boxplot(aes(fill=label)) + ggtitle(var)
    P <- c(P, list(p))
  }
  return(list(plots=P, num=length(vars)))
}

PLOTS <- plotting(d)
do.call(grid.arrange, c(PLOTS$plots, nrow = PLOTS$num))
like image 181
shadow Avatar answered Oct 30 '22 22:10

shadow