[R] Creating grid graphics with grid.layout

Jeff Horner jeff.horner at vanderbilt.edu
Fri Sep 25 01:55:31 CEST 2009


Paul Murrell wrote:
> Hi
> 
> If using integer indices is awkward, you could push a viewport tree with 
> the relevant viewports given useful names.  Then you can downViewport() 
> using the names (if those plots are lattice plots, then you might even 
> be able to use the 'draw.in' argument).  Is that the sort of thing you 
> are looking for?

Actually no, integer is just fine, and querying viewports by name would 
be slower, no?. I more wanted to confirm that my approach was sound, 
using lapply and loops, and that I was using as much of the grid 
vectorizing features that were available. For instance, a few iterations 
ago I attempted to construct what I thought was a vector of viewports 
like so:

x <- c(2,4,2,4)
y <- c(2,2,4,4)
print(...,vp=viewport(layout.pos.col=x,layout.pos.row=y)

which would print ... to each viewport. I realize now that specifying a 
vector for layout.pos.* args is just to construct one larger viewport of 
the adjacent viewports, right?

Thanks for the quick feedback!

Jeff

> Paul
> 
> 
> Jeff Horner wrote:
>> Hi,
>>
>> I recently created a function which uses grid with a viewport 
>> constructed with grid.layout() to position four plots on a plot 
>> device. My question is what's the best way to programatically traverse 
>> each element of the viewport?
>>
>> The grid is 5x5 and the four plots occupy positions (2,2), (4,2), 
>> (2,4), and (4,4).
>>
>> Here's the viewport code:
>>
>>   pushViewport(
>>          viewport(
>>              layout=grid.layout(
>>                  nrow=5,
>>                  ncol=5,
>>                  widths=unit(
>>                      c(margin[2],1,margin[6],1,margin[4]),
>>                      c('npc','null','npc','null','npc')),
>>                  heights=unit(
>>                      c(margin[3],1,margin[5],1,margin[1]),
>>                      c('npc','null','npc','null','npc'))
>>              )
>>          )
>>      )
>>
>> margin is a numeric vector of length 6 which resp defines the bottom, 
>> left, top, right, horizontal, and veritical margins (the cross hairs 
>> between the 4 plots). This is to allow the user to define how much 
>> margin should exist around all plots and between the plots.
>>
>> I then use lapply to visit only those viewports to place the plots by 
>> specifying an x and y vector like so:
>>
>> x <- c(2,4,2,4)
>> y <- c(2,2,4,4)
>> i <- 1
>> lapply(list(plot1,plot2,plot3,plot4),function(j){
>>     print(j,vp=viewport(layout.pos.col=x[i],layout.pos.row=y[i])
>>     i <<- i + 1
>> })
>>
>> Looks kludgey. Is there a better way?
>>
>> Also, I created debug code to visit those viewports where *nothing* is 
>> supposed to be printed except for a grey box with black edges:
>>
>> z <- outer(logical(5),logical(5),"==")
>> for (i in 1:length(x)) z[x[i],y[i]] <- FALSE
>> for (i in 1:5){
>>     for (j in 1:5){
>>        if (z[i,j])
>>           grid.rect(gp=gpar(fill="grey"),
>>             vp=viewport(layout.pos.col=i,layout.pos.row=j))
>>     }
>> }
>>
>> This looks kludgey as well. Any other ways outer there that are more 
>> elegant?
>>
>> Thanks,
>>
>> Jeff
>>
>> ______________________________________________
>> R-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide 
>> http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>




More information about the R-help mailing list