From ggrothendieck at gmail.com  Sun May 21 19:33:41 2006
From: ggrothendieck at gmail.com (Gabor Grothendieck)
Date: Sun, 21 May 2006 13:33:41 -0400
Subject: [Rd] print.trellis(..., draw.in=...)
In-Reply-To: <eb555e660605211019s31fac589hb4107dd88c6f69c6@mail.gmail.com>
References: <971536df0605210441s5833a4cdr8286fdd23f560b7c@mail.gmail.com>
	<eb555e660605211019s31fac589hb4107dd88c6f69c6@mail.gmail.com>
Message-ID: <971536df0605211033j7a57be5eo78d029d0ac489846@mail.gmail.com>

Thanks.  I should have realized that.  Now that I read it again with
your explanation it is clear.

At the same time it would be convenient if one could specify a viewport
or vpPath, as well.  If that were the case we could also eliminate the
names.* methods in this example. (These were included to encapsulate
access to them so that the main code does not muck around in the
internals.)

At any rate, for the record, here is the code again corrected:

library(grid)
library(lattice)

pushLayout <- function(nr, nc, name="layout") {
 pushViewport(viewport(layout=grid.layout(nr, nc), name=name))
 for (i in 1:nr) {
   for (j in 1:nc) {
     pushViewport(viewport(layout.pos.row=i, layout.pos.col=j))
     upViewport()
   }
 }
 upViewport()
}

names.vpPath <- names.viewport <- function(x) x$name

getChildren.viewport <- function(x) x$children

grid.newpage()

# specify number of cells to fill and number of rows
n <- 5; nr <- 3

nc <- ceiling(n/nr)
downViewport(pushLayout(nr, nc))

vpt <- current.vpTree(all = FALSE)
children <- getChildren.viewport(vpt)
for(k in 1:n)
     print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE,
               draw.in = names(children[[k]]) )


On 5/21/06, Deepayan Sarkar <deepayan.sarkar at gmail.com> wrote:
> On 5/21/06, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:
> > A year ago I had posted this code
> >
> > https://stat.ethz.ch/pipermail/r-devel/2005-June/033508.html
> >
> > and the associated discussion was that there would be a print.trellis
> > argument that could be used to eliminate the need for with.vpPath
> > or with.viewport there.  I assume that that is what draw.in= in
> > print.trellis is for.  When I try it I get an error.  I did notice that
> > ?print.trellis says draw.in= has not been well tested yet.  Is
> > this a bug?
>
> No, but perhaps a lack of clarity in the documentation. ?print.trellis says:
>
>  draw.in: An optional (grid) viewport (used as the 'name' argument in
>          'downViewport') in which the plot is to be drawn.  ...
>
> and ?downViewport says
>
>    name: A character value to identify a viewport in the tree.
>
> Your code supplies viewports, not character names (in the older
> working example, you did this conversion inside with.vpPath).
>
> -Deepayan
>
> > After running the the code at the end I get this error
> > message:
> >
> >  Error in downViewport.vpPath(vpPathDirect(name), strict, recording =
> > recording) :
> >         Viewport 'viewport[GRID.VP.1]' was not found
> >
> > The only difference between the code below and the code in the
> > link above (which works) is that in the for loop at the end the
> > 'with' in the code in the link has been removed and draw.in=
> > used in the print call in its place.
> >
> > I am using Windows XP and get similar messages in 2.2.1 and
> > 2.3.0 patched.
> >
> >
> > library(grid)
> > library(lattice)
> >
> > pushLayout <- function(nr, nc, name="layout") {
> >   pushViewport(viewport(layout=grid.layout(nr, nc), name=name))
> >   for (i in 1:nr) {
> >     for (j in 1:nc) {
> >       pushViewport(viewport(layout.pos.row=i, layout.pos.col=j))
> >       upViewport()
> >     }
> >   }
> >   upViewport()
> > }
> >
> > names.vpPath <- names.viewport <- function(x) x$name
> >
> > with.vpPath <- with.viewport <- function(data, expr, ...) {
> >       # if data is a vpPath it cannot be ROOT since
> >       # NULL will never dispatch here
> >       depth <- if (data$name == "ROOT") 0 else downViewport(names(data))
> >       result <- eval.parent(substitute(expr))
> >       upViewport(depth)
> >       invisible(result)
> > }
> >
> > getChildren.viewport <- function(x) x$children
> >
> > grid.newpage()
> >
> > # specify number of cells to fill and number of rows
> > n <- 5; nr <- 3
> >
> > nc <- ceiling(n/nr)
> > downViewport(pushLayout(nr, nc))
> >
> > vpt <- current.vpTree(all = FALSE)
> > for(k in 1:n)
> >       print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE,
> >                 draw.in = getChildren.viewport(vpt)[[k]] )
>



[Rd] print.trellis(..., draw.in=...)
Gabor Grothendieck