From p.murrell at auckland.ac.nz  Wed Jun  8 03:47:27 2005
From: p.murrell at auckland.ac.nz (Paul Murrell)
Date: Wed Jun  8 03:47:38 2005
Subject: [Rd] Re: [R] Problem going back to a viewport with gridBase
References: <971536df05053020191ebe8f44@mail.gmail.com>	
	<429CFA42.4080106@stat.auckland.ac.nz>	
	<971536df05053118215366e02c@mail.gmail.com>	
	<429E5BFD.9080508@stat.auckland.ac.nz>	
	<971536df050602140356cc80b4@mail.gmail.com>	
	<429FB4AE.5030105@stat.auckland.ac.nz>	
	<971536df0506030554396c2374@mail.gmail.com>	
	<42A4D286.5090208@stat.auckland.ac.nz>	
	<971536df0506061924438870f0@mail.gmail.com>	
	<42A612FF.5020408@stat.auckland.ac.nz>
	<971536df05060718376e609133@mail.gmail.com>
Message-ID: <42A64E2F.7030707@stat.auckland.ac.nz>

Hi


Gabor Grothendieck wrote:
> On 6/7/05, Paul Murrell <p.murrell@auckland.ac.nz> wrote:
> 
>>Hi
>>
>>
>>Gabor Grothendieck wrote:
>>
>>>On 6/6/05, Paul Murrell <p.murrell@auckland.ac.nz> wrote:
>>>
>>>
>>>>Hi
>>>>
>>>>
>>>>Gabor Grothendieck wrote:
>>>>
>>>>
>>>>>On 6/2/05, Paul Murrell <p.murrell@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.


I agree that a childNames() method for a viewport tree is probably 
reasonable.  The subtle problem is the fact that your code makes use of 
the *order* of the names that function would return, when in fact there 
is no claim that they will be in any particular order.

Paul


>>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@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@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@stat.auckland.ac.nz
http://www.stat.auckland.ac.nz/~paul/


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