From p.murrell at auckland.ac.nz  Sun Jan 27 22:13:02 2008
From: p.murrell at auckland.ac.nz (Paul Murrell)
Date: Mon, 28 Jan 2008 10:13:02 +1300
Subject: [Rd] seekViewport error
In-Reply-To: <971536df0801231922w17c7f94fr9fdc6d9a46a8853d@mail.gmail.com>
References: <971536df0712261026w6bdebe49re08ed45e28af8873@mail.gmail.com>	
	<4797FA21.3090700@stat.auckland.ac.nz>
	<971536df0801231922w17c7f94fr9fdc6d9a46a8853d@mail.gmail.com>
Message-ID: <479CF3DE.8020007@stat.auckland.ac.nz>

Hi


Gabor Grothendieck wrote:
> On Jan 23, 2008 9:38 PM, Paul Murrell <p.murrell at auckland.ac.nz> wrote:
>> Hi
>>
>>
>> Gabor Grothendieck wrote:
>>> Why does the seekViewport at the bottom give an error?
>>
>> Because the viewport is popped after GRID.cellGrob.84 is drawn.
>>
>> grid.ls() shows the viewport because it recurses down into the legend
>> frame grob.  Compare your output with (grid-generated numbering differs)
>>  ...
>>
>>  > grid.ls(recurs=FALSE, view=TRUE)
>> ROOT
>>   GRID.rect.28
>>   plot1.toplevel.vp
>>     plot1.xlab.vp
>>       plot1.xlab
>>       1
>>     plot1.ylab.vp
>>       plot1.ylab
>>       1
>>     plot1.strip.1.1.off.vp
>>       GRID.segments.29
>>       1
>>     plot1.strip.left.1.1.off.vp
>>       GRID.segments.30
>>       GRID.text.31
>>       1
>>     plot1.panel.1.1.off.vp
>>       GRID.segments.32
>>       GRID.text.33
>>       GRID.segments.34
>>       1
>>     plot1.panel.1.1.vp
>>       GRID.points.35
>>       GRID.points.36
>>       GRID.points.37
>>       1
>>     plot1.panel.1.1.off.vp
>>       GRID.rect.38
>>       1
>>     plot1.legend.top.vp
>>       GRID.frame.9
>>       1
>>     plot1.
>>       1
>>     1
>>
>> If you look at what viewports are actually available, via
>> current.vpTree(), you'll see that GRID.VP.24 is not there.
>>
>> The problem (see also
>> https://stat.ethz.ch/pipermail/r-help/2008-January/151655.html) is that
>> cellGrobs (children of frame grobs) use their 'vp' component to store
>> the viewport that positions them within the parent frame.  This means
>> that the viewport is pushed and then popped (as per normal behaviour for
>> 'vp' components).
>>
>> A possible solution that I am currently trialling uses a special
>> 'cellvp' slot instead so that the cellGrob viewports are pushed and then
>> "upped".  That way they remain available after the cellGrob has drawn,
>> so you can downViewport() to them.
>>
>> The disadvantage of this approach is that the viewports no longer appear
>> in the grid.ls() listing (because grid.ls() has no way of knowing about
>> special components of grobs that contain viewports).  This effect can
>> already be seen by the fact that the viewport for the frame grob
>> (GRID.frame.70) is not shown in the grid.ls() output.  On the other
>> hand, the viewports will be visible via current.vpTree()  ...
> 
> Perhaps some convention could be adopted which, if followed, would
> let grid.ls know?  If that worked at least for graphics generated from
> lattice and ggplot2 that would likely satisfy a significant percentage
> of uses.


The gridList() function used by grid.ls() is generic, so a solution is
to simply write a method for frames and cellGrobs.  I have committed a
fix along these lines.

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/



[Rd] seekViewport error
Paul Murrell