From paul at stat.auckland.ac.nz  Tue Feb 15 19:51:16 2011
From: paul at stat.auckland.ac.nz (Paul Murrell)
Date: Wed, 16 Feb 2011 07:51:16 +1300
Subject: [Rd] gList and gTree methods of grid::grobX
In-Reply-To: <AANLkTikH-c7EECcu8fpgxrMGShXnX5hR3tPmy1izPafx@mail.gmail.com>
References: <AANLkTikH-c7EECcu8fpgxrMGShXnX5hR3tPmy1izPafx@mail.gmail.com>
Message-ID: <4D5ACB24.1000909@stat.auckland.ac.nz>

Hi

baptiste auguie wrote:
> Dear all,
> 
> In an attempt to draw fill patterns in grid graphics, I have
> encountered a behavior of grobX that I cannot understand from the
> documentation. Consider this,
> 
> library(grid)
> 
> ## gTree
> g1 <- gTree(children=gList(
>              rectGrob(0.5,0.5, width=unit(0.8,"npc"),
>                       height=unit(2,"cm")),
>              circleGrob(r=0.3)), vp=viewport(0.5,0.5))
> 
> ## gList
> g1 <- gList(rectGrob(0.5,0.5, width=unit(0.8,"npc"),
>                      height=unit(2,"cm")),
>             circleGrob(r=0.3))
> 
> ## loop over angles to map the boundary
> gtheta <- function(g, theta){
> 
>   sapply(theta, function(.t){
>          gx <- convertX(grobX(g, .t), "npc")
>          gy <- convertY(grobY(g, .t), "npc")
> 
>          c(gx,gy)
>        })
> 
> }
> 
> angles <- seq(0,360,by=30)
> p1 <- gtheta(g1, angles)
> 
> grid.newpage()
> grid.draw(g1)
> grid.points(p1[1,],p1[2,], gp=gpar(cex=0.2),
>             default.units="npc")
> 
> 
> If I'm not mistaken, neither gList nor gTree seem to produce the
> documented behavior,
> 
> "If the grob describes multiple shapes, the boundary value will either
> correspond to the edge of a bounding box around all of the shapes
> described by the grob (for multiple rectangles, circles, xsplines, or
> text), or to a convex hull around all vertices of all shapes described
> by the grob (for multiple polygons, points, lines, polylines, and
> segments)."

That description is referring to a single *grob* object that draws 
multiple shapes, something like ...

g1 <- circleGrob(x=1:3/4, y=1:3/4, r=.1)

... in your example.

The behaviour of gTrees is pretty much undefined, but the user is free 
to slap a class on the gTree and write their own xDetails() and 
yDetails() methods to achieve the outcome that they want.  I have 
wondered about supplying a default that makes some sort of union of the 
boundaries of the children of a gTree, but have not yet implemented that.

The gList case has been explicitly coded to produce the result from the 
last object in the gList, but I cannot recall why I ever thought that 
might be a good default.  Again, making the gList the children of a 
gTree with a specific class provides the opportunity to control what 
grobX() and grobY() return for yourself.

Paul

> with gList, I observe that the boundary is only considered for the
> first shape, whilst gTree ignores all children altogether.
> 
> It works fine for single shapes (e.g. g1 = circleGrob(r=0.3)).
> 
> The same behavior is observed with quartz(), pdf() and png().
> 
> 
> Sincerely,
> 
> baptiste
> 
> sessionInfo()
> R version 2.12.1 Patched (2010-12-30 r53895)
> Platform: i386-apple-darwin9.8.0 (32-bit)
> 
> locale:
> [1] en_GB.UTF-8/en_GB.UTF-8/C/C/en_GB.UTF-8/en_GB.UTF-8
> 
> attached base packages:
> [1] grid      stats     graphics  grDevices utils     datasets
> methods   base
> 
> loaded via a namespace (and not attached):
> [1] tools_2.12.1
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
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/



[Rd] gList and gTree methods of grid::grobX
Paul Murrell