Device independent subplots with viewpoints

20 views
Skip to first unread message

Herbert Jägle

unread,
Jul 19, 2009, 9:50:22 AM7/19/09
to ggplot2
As part of a large project i'd like to use subplots to arrange a
larger number of small graphs. For all subplots i have the size and
center of the subplot (which are irregularly distributed).

In the examples of the manual the main plot and all subplots are
created, a PDF device opened and the main and all subplots added with
"print". The the device is closed. That's how i understand it.

I would like to create my plots device independent (mostly using
windows and PDF) and can not figure out how.

How do i create a basic device independent plot (completely empty)
which i can use to add subplots with "print" or some equivalent?

Is it possible to use ggsave to save the entire plot to a specific
device?

By the way: How can i force the x-axis and y-axis being device
independent of the same size (exactly quadratic) if i use facet_grid?

Thanks
Herbert

baptiste auguie

unread,
Jul 19, 2009, 10:48:27 AM7/19/09
to Herbert Jägle, ggplot2
Hi,

The general idea is to create a grid.layout of viewports using Grid,
then print the plots using the vp argument. AFAIK it should be the
same procedure for all devices. Perhaps the following function can
inspire you,

vp.layout =
function (x, y)
viewport(layout.pos.row = x, layout.pos.col = y)

arrange =
function (..., nrow = NULL, ncol = NULL, as.table = F)
{
dots <- list(...)
n <- length(dots)
if (is.null(nrow) & is.null(ncol)) {
nrow = floor(n/2)
ncol = ceiling(n/nrow)
}
if (is.null(nrow)) {
nrow = ceiling(n/ncol)
}
if (is.null(ncol)) {
ncol = ceiling(n/nrow)
}
grid.newpage()
pushViewport(viewport(layout = grid.layout(nrow, ncol)))
ii.p <- 1
for (ii.row in seq(1, nrow)) {
ii.table.row <- ii.row
if (as.table) {
ii.table.row <- nrow - ii.table.row + 1
}
for (ii.col in seq(1, ncol)) {
ii.table <- ii.p
if (ii.p > n)
break
print(dots[[ii.table]], vp = vp.layout(ii.table.row,
ii.col))
ii.p <- ii.p + 1
}
}
}


p1 = qplot(1,1)
p2 = qplot(1:10,1:10)

arrange(p1, p2) # interactive use (tested on quartz())

pdf()
arrange(p1,p2, ncol=1) # you'll need to define a more general way
# to specify the positions and dimensions
dev.off()

On Sun, Jul 19, 2009 at 3:50 PM, Herbert
Jägle<herbert...@uni-tuebingen.de> wrote:
>
> As part of a large project i'd like to use subplots to arrange a
> larger number of small graphs. For all subplots i have the size and
> center of the subplot (which are irregularly distributed).
>
> In the examples of the manual the main plot and all subplots are
> created, a PDF device opened and the main and all subplots added with
> "print". The the device is closed. That's how i understand it.
>
> I would like to create my plots device independent (mostly using
> windows and PDF) and can not figure out how.
>
> How do i create a basic device independent plot (completely empty)
> which i can use to add subplots with "print" or some equivalent?
>
> Is it possible to use ggsave to save the entire plot to a specific
> device?

The book says "no" (p. 153).


HTH,

baptiste

Herbert Jägle

unread,
Jul 19, 2009, 4:03:25 PM7/19/09
to ggplot2, baptiste auguie
Baptiste,

thanks for you suggestion. As of my understanding, the grid.layout is
always rectangular.

What i am looking for is almost free positioning of the subplots. For
example, an arrangement could be a dartboard, where each field
contains a plot or a country map where you add a plot at the position
of a city or similar (just for imagination).

Regards,
Herbert

baptiste auguie

unread,
Jul 19, 2009, 4:18:52 PM7/19/09
to Herbert Jägle, ggplot2
in that case you'll need to provide the user with a way to specify the
position and size of each viewport. For instance, (click twice on an
interactive device)

p1 = qplot(1,1)
p2 = qplot(1:10,1:10)

# size of the viewports in native units
widths = c(0.5, 0.2)
heights = c(0.3, 0.3)

grid.newpage()
l1 = grid.locator() # click on the page where you want your first plot
vp1 = viewport(x=l1$x, y= l1$y, width= widths[1], height=heights[1])
print(p1, vp = vp1)
l2 = grid.locator()# click on the page where you want your second plot
vp2 = viewport(x=l2$x, y= l2$y, width= widths[2], height=heights[2])
print(p2, vp = vp2)

And of course you may replace grid.locator() with previously defined
coordinates. A trickier part might be for you to place the viewports
so that they use the available nicely. Grid provides some utilities
that might help you (grid.pack etc.).

--
_____________________________

Baptiste Auguié

School of Physics
University of Exeter
Stocker Road,
Exeter, Devon,
EX4 4QL, UK

http://newton.ex.ac.uk/research/emag
______________________________

Reply all
Reply to author
Forward
0 new messages