2

I posted this question earlier but it turns out that the answer I confirmed has a problem, so I'm posting this again with a hope to get a fix on that.

I have the following data.frame which I would like to plot to a file with ggplot2:

df = data.frame(mean=c(1.96535,2.133604,1.99303,1.865004,2.181713,1.909511,2.047971,1.676599,2.143763,1.939875,1.816028,1.95465,2.153445,1.802517,2.141799,1.722428),
sd=c(0.0595173,0.03884202,0.0570006,0.04934336,0.04008221,0.05108064,0.0463556,0.06272475,0.04321496,0.05283728,0.05894342,0.05160038,0.04679423,0.05305525,0.04626291,0.0573123),
par=as.factor(c("p","p","m","m","p","p","m","m","m","m","p","p","m","m","p","p")),
group=as.factor(c("iF","iF","iF","iF","iM","iM","iM","iM","RF","RF","RF","RF","RM","RM","RM","RM")),
rep=c(1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2)) 

This is my code for producing the ggplot2 object that:

p <- ggplot(df,aes(factor(rep),y=mean,ymin=mean-2*sd,ymax=mean+2*sd,color=factor(par)))
p <- p + geom_pointrange()+facet_wrap(~group, ncol = 4)+scale_color_manual(values = c("blue","red"),labels = c("p","m"),name = "par id")
p <- p + ggtitle("test")
p <- p + labs(y="log(y)",x="rep")

What I'm trying to do in addition is to add this data.frame as a table under the legend:

leg.df = data.frame(statistic = c("pp(par)","pp(g)","pp(s)","fc(p/m)"), value = c(0.96,0.94,0.78,1.5))

I got this solution for doing that:

leg.df.grob <-  tableGrob(leg.df, gpar.coretext =gpar(fontsize=8),
         par.coltext=gpar(fontsize=8), 
         gpar.rowtext=gpar(fontsize=8))

### final result
library(gridExtra)
pp <- arrangeGrob(p + theme(legend.position = "none"), 
                  arrangeGrob(leg.df.grob, legend), ncol = 2)

And then, theoretically, I can save pp to a file, for example, using:

ggsave('plot.png',pp)

Unfortunately, the command:

pp <- arrangeGrob(p + theme(legend.position = "none"), 
                      arrangeGrob(leg.df.grob, legend), ncol = 2) 

causes the plot device to open (which is exactly what I'm trying to avoid), and in addition it's throwing this error:

Error in arrangeGrob(leg.df.grob, legend) : input must be grobs!

Any idea how to fix this?

Community
  • 1
  • 1
user1701545
  • 5,706
  • 14
  • 49
  • 80
  • You should not ask twice the same question. If you have any problem with the accepted solution you can un-accept it (uncheck it) and comment the answer with your problem. – agstudy Dec 08 '13 at 17:24
  • I agree and I feel bad for that. However, aside from un-accepting the answer (which I did just now), I added two comments and got no response over a couple of days. But re-posting it got many views and your acceptable answer within minutes. – user1701545 Dec 08 '13 at 17:57

1 Answers1

4

The other solution is correct. I guess you get an error because you don't set the legend variable. So arrangeGrob is called with the R function legend as argument. You should define legend as:

g_legend <- function(a.gplot){
    tmp <- ggplot_gtable(ggplot_build(a.gplot))
    leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
    legend <- tmp$grobs[[leg]]
    return(legend)
}
legend <- g_legend(p)

I slightly modify the other answer, to better rearrange grobs by setting widths argument:

pp <- arrangeGrob(p + theme(legend.position = "none"), 
                  widths=c(3/4, 1/4),
                  arrangeGrob( legend,leg.df.grob), ncol = 2)

enter image description here

agstudy
  • 119,832
  • 17
  • 199
  • 261
  • Thanks a lot. This works now, but for completeness I should add that the graphics device opens automatically, regardless if I'm using ggsave or not, so one may want to add dev.off() after the ggsave command. A related minor question: any idea how to replace the "M" and "F" characters in the plot header with the male and female sex symbols? – user1701545 Dec 08 '13 at 17:47