[Rd] Re: [R] Problem going back to a viewport with gridBase

Gabor Grothendieck ggrothendieck at gmail.com
Wed Jun 8 03:37:00 CEST 2005


On 6/7/05, Paul Murrell <p.murrell at auckland.ac.nz> wrote:
> Hi
> 
> 
> Gabor Grothendieck wrote:
> > On 6/6/05, Paul Murrell <p.murrell at auckland.ac.nz> wrote:
> >
> >>Hi
> >>
> >>
> >>Gabor Grothendieck wrote:
> >>
> >>>On 6/2/05, Paul Murrell <p.murrell at auckland.ac.nz> wrote:
> >>>
> >>>
> >>>>Hi
> >>>
> >>>
> >>>Thanks.  I have mucked around in vpTree structures and discovered its
> >>>actually quite easy to specify children so I have changed my example
> >>>so that instead of naming the children of 'layout' and then remembering
> >>>coordinates linked to the names of the children of 'layout' in
> >>>the 'coords' structure (which really just duplicates state information
> >>>already available in grid) it simply follows the order
> >>>of the children of 'layout' directly.  This permits elimination of 'coords'
> >>>and the two naming functions.  Using the depth approach you advocate,
> >>>'with' also becomes shorter and I think I have it to the point where it works
> >>>with both vpPath and viewport classes.  Once Deepayan implements
> >>>the use.viewport= argument to print, 'with' can be eliminated too.  No
> >>>questions this time but I thought I would post the latest version for
> >>>completeness. Regards.
> >>
> >>
> >>Ok.  I can see this working ... for now.  The disadvantage with this
> >>approach is that it makes use of the undocumented, internal structure of
> >>a viewport tree to grab a list of child viewports.  A worse example of
> >>the same thing is that the with() methods make use of a happy
> >>coincidence that both viewport objects and viewport path objects share a
> >>component called "name" (and an even happier coincidence that they
> >>contain the same information).  I think it would be cleaner and better
> >>practice, despite requiring longer code, to make use of the documented
> >>interface which requires specifying viewport names and viewport paths.
> >>The internal structure of objects is not guaranteed to be stable.
> >
> >
> > Perhaps accessor functions could be provided that allow one to
> > retrieve the name of a viewport and the name of a vpPath in
> > a safe way.  These could be as simple as:
> >
> > names.viewport <- names.vpPath <- function(x) x$name
> 
> 
> Fair enough.  If I say "use the API", I should provide a useful API :)
> 
> This is a reasonable request for viewports;  the "name" component of a
> viewport is a sensible thing to want.
> 
> OTOH, it is not necessarily reasonable for a viewport path;  not all
> components of an object should necessarily have accessors.  The "name"
> component of a viewport path is the last element in the path.  Perhaps
> an API should be supplied for extracting parts of a viewport path, but
> it should probably be something along the lines of car()/cdr() or
> head()/tail() or explode() to get different bits of the path.
> 
> Accessing the children of a viewport is subtly problematic too.
> Directly accessing the "children" slot and using the order of the
> children in that slot is "dangerous" because there is no claim made by
> the system as to how the children are internally ordered.  Again, it
> works currently, but it makes incorrect assumptions about what the
> system is doing internally so is vulnerable to future changes.

That is the point of an accessor.  If the internals change then the
accessor is modified to hide the change so that the user using the
accessor is not impacted.  

It seems that grid already partly supports this with the childNames
function.  It could be made generic and a method provided
to cover the classes discussed here too.

> 
> So again, the recommended approach is to use the API provided;  you
> provide the naming scheme for viewports and you control the order in
> which viewports are used.
> 
> Paul
> 
> 
> > Similarly an accessor function to safely retrieve the children would
> > be nice.    Again, it should ideally be possible to
> > have a generic with methods for various grid classes.
> >
> > Then the  relevant line in the code concerning name
> > could be written in a safe way like this:
> >
> > depth <- if (data$name == "ROOT") 0 else downViewport(names(data))
> >
> > and similarly for the children.
> >
> >
> >
> >>Paul
> >>
> >>
> >>
> >>>[pushLayout is same as before except there are no names on the
> >>>children of 'layout' and the rest is new]
> >>>
> >>>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()
> >>>}
> >>>
> >>>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(data$name)
> >>>      result <- eval.parent(substitute(expr))
> >>>      upViewport(depth)
> >>>      invisible(result)
> >>>}
> >>>
> >>>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) with(vpt$children[[k]],
> >>>      print( xyplot(v ~ v, list(v = 1:k)), newpage = FALSE )
> >>>)
> >>
> >>
> >>--
> >>Dr Paul Murrell
> >>Department of Statistics
> >>The University of Auckland
> >>Private Bag 92019
> >>Auckland
> >>New Zealand
> >>64 9 3737599 x85392
> >>paul at stat.auckland.ac.nz
> >>http://www.stat.auckland.ac.nz/~paul/
> >>
> >
> >>
> 
> 
> --
> Dr Paul Murrell
> Department of Statistics
> The University of Auckland
> Private Bag 92019
> Auckland
> New Zealand
> 64 9 3737599 x85392
> paul at stat.auckland.ac.nz
> http://www.stat.auckland.ac.nz/~paul/
> 
>



More information about the R-devel mailing list