grid.arrange, grid.layout - legend, global y axis title

3,003 views
Skip to first unread message

Johannes Radinger

unread,
Nov 15, 2011, 9:26:14 AM11/15/11
to ggp...@googlegroups.com, r-h...@r-project.org
Hello,

I created several plot with ggplot2 dev mode.

Now I want to combine the plots in a grid
e.g. 2x2 with a fixed size of the output.

What I am doing at the moment is:

grid.newpage()
pushViewport(viewport(layout = grid.layout(nrow=2, ncol=2,
widths = unit(c(7.5,6.5), "cm"),
heights = unit(rep(5, 2), "cm"))))
print(plot1, vp = viewport(layout.pos.row = 1, layout.pos.col = 1))
print(plot2, vp = viewport(layout.pos.row = 1, layout.pos.col = 2))
print(plot3, vp = viewport(layout.pos.row = 2, layout.pos.col = 1))
print(plot4, vp = viewport(layout.pos.row = 2, layout.pos.col = 2))


This is working well so far.

The y-axis are for all plots the same so I'd like to have a global y-axis title on the left side. How can that be done using my approach?

I also would like to add a global vertical legend for my plots below all plots.
The legend should show the to different symbols (same as for the single plots (ggplot2)). I also don't know how to do that.

I know that there is the function grid.arrange which can do both things but this isn't working because I am in the dev mode of ggplot. Then I get the error: Error: could not find function "ggplotGrob.

I load my libraries the following way:

1) import data
2) load library(gridExtra)
3) load library(devtools)
dev_mode(TRUE)
library(ggplot2)
library(reshape2)
4) produce plots
5) arrange the plots.

So what is the best way to proceed?
Should I stay with the grid.layout approach and can I get there a global legend and a global y axis title?
Or how can I use grid.arrange, define the position of the gobal legend and set the single plot to a fixed size?

I hope that wasn't to complicated...

/Johannes

--
NEU: FreePhone - 0ct/min Handyspartarif mit Geld-zurück-Garantie!
Jetzt informieren: http://www.gmx.net/de/go/freephone

baptiste auguie

unread,
Nov 15, 2011, 4:46:19 PM11/15/11
to Johannes Radinger, ggp...@googlegroups.com, r-h...@r-project.org
Hi,

Please don't cross post.

It seems that ggplotGrob has been replaced by new functions. You can
define it as

ggplotGrob <- function(x) ggplot2:::gtable_gTree(ggplot2:::ggplot_gtable(x))

and it seems to work as before with grid.arrange().

HTH,

baptiste

> --
> You received this message because you are subscribed to the ggplot2 mailing list.
> Please provide a reproducible example: http://gist.github.com/270442
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2
>

Johannes Radinger

unread,
Nov 16, 2011, 5:59:11 AM11/16/11
to baptiste auguie, ggp...@googlegroups.com
Hi,

thank you Baptiste for the function for ggplotGrob.

Now grid.arrange works fine as before. I am just
wondering how to set the absolute size of the single
plots? Is that possible in general.
Before I did a different approach with:


pushViewport(viewport(layout = grid.layout(nrow=2, ncol=2,
widths = unit(c(7.5,6.5), "cm"),
heights = unit(rep(5, 2), "cm"))))

How can I set such column widths with grid.arrange.

Today I try also to include a global legend, which should
be vertically arranged and should be placed below all plots.
Hopefully I can manage to do that with grid.arrange.

best regards,
Johannes


-------- Original-Nachricht --------
> Datum: Wed, 16 Nov 2011 10:46:19 +1300
> Von: baptiste auguie <bapt...@googlemail.com>
> An: Johannes Radinger <JRad...@gmx.at>
> CC: ggp...@googlegroups.com, r-h...@r-project.org
> Betreff: Re: grid.arrange, grid.layout - legend, global y axis title

baptiste auguie

unread,
Nov 16, 2011, 2:33:01 PM11/16/11
to Johannes Radinger, ggp...@googlegroups.com
Hi,

You can pass width and height to grid.arrange,

p = rectGrob()
grid.arrange(p,p,p,p, ncol=2, widths = unit(c(7.5,6.5), "cm"),
heights = unit(rep(1, 2), "cm"))

HTH,

baptiste

Johannes Radinger

unread,
Nov 17, 2011, 5:55:36 AM11/17/11
to baptiste auguie, ggp...@googlegroups.com
Hello Baptiste,
Hello others,

good to know that the absolut witdhts and heights can also be set in
grid.arrange.

I played a little around with the global y axis and the legend, but I don't know how to modify how I want it. My problems/wishes:

1) As I set fixed heights and width, my global y axis is far away from my plots. How can I manage to get it next to the plots on the left side?

2) Somehow I don't manage to get the legend properly. I'd like the legend in a row (2 factors only) and the legend should be placed below the plots not right to it. Probably I can just create the legend manually (with text and symbols) and place it as a graphic below. I don't know what is the best way.

Here an example (sorry for the length):

#creating sample data and dataframe
pred.x1 <-runif(5, 5.0, 7.5)
pred.x2 <- runif(5,0.1,0.9)
resp.y1 <- runif(5,1,10)
resp.y2 <- runif(5,30,50)
df1 <- data.frame(pred.x1,pred.x2,resp.y1,resp.y2)
#reshape dataframe for this approach
df3 <-reshape2:::melt.data.frame(df1,id=c("pred.x1", "pred.x2"),variable.name="resp.name",value.name="resp.value")


#create single plots
plot.grid1 <- ggplot(df3, aes(x=pred.x1,y=resp.value,shape=resp.name))+
geom_point()+
scale_shape_manual(values=c(21,16))+
theme_bw()+
opts( axis.title.x = theme_blank(),
axis.title.y = theme_blank())

plot.grid2 <- ggplot(df3, aes(x=pred.x2,y=resp.value,shape=resp.name))+
geom_point()+
scale_shape_manual(values=c(21,16))+
theme_bw()+
opts( axis.title.x = theme_blank(),
axis.title.y = theme_blank())

# create legend
leg <- ggplotGrob(plot.grid1 + opts(keep="legend_box")) ## one needs to provide the legend with a well-defined width
legend=gTree(children=gList(leg), cl="legendGrob")
widthDetails.legendGrob <- function(x) unit(2, "cm")

grid.arrange(
plot.grid1 + opts(legend.position="none"),
plot.grid2 + opts(legend.position="none"),
nrow=1, ncol=2,


widths = unit(c(7.5,6.5), "cm"),

heights = unit(rep(5, 1), "cm"),
legend=legend,
left = "This is my global Y-axis title")


Maybe you know how realise that.

Thank you,

Johannes

-------- Original-Nachricht --------
> Datum: Thu, 17 Nov 2011 08:33:01 +1300


> Von: baptiste auguie <bapt...@googlemail.com>
> An: Johannes Radinger <JRad...@gmx.at>
> CC: ggp...@googlegroups.com

baptiste auguie

unread,
Nov 17, 2011, 2:32:56 PM11/17/11
to Johannes Radinger, ggp...@googlegroups.com
Hi,

I don't know the new internals of ggplot2 so I'm not sure how one can
extract the legend as an independent grob. I know there are options
however (opts()) to display the legend horizontally, and at the bottom
of a plot. Are you sure your plot cannot be made with a dummy
facetting variable?


baptiste

Johannes Radinger

unread,
Nov 21, 2011, 5:13:04 AM11/21/11
to baptiste auguie, ggp...@googlegroups.com
Hi,


> Hi,
>
> I don't know the new internals of ggplot2 so I'm not sure how one can
> extract the legend as an independent grob. I know there are options
> however (opts()) to display the legend horizontally, and at the bottom
> of a plot. Are you sure your plot cannot be made with a dummy
> facetting variable?

It is nearly possible to make my plot with a dummy facetting variable, actually I would like to do it with the facett approach. But there is a problem: I need really "free" x axis. Some of them have to be log scaled while others not. I don't know of any possibilty to mix two different axis scales for the x axis in a dummy facett plot? Is somebody aware of such a feature maybe in the ggplot2-dev???

If not I think I have to stay with the manual grid.arrange approach. But then I' need to extract the legend? Does anyone know if is possible to extract the legend as an independent grob?

/Johannes

Reply all
Reply to author
Forward
0 new messages