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

From: Paul Murrell <p.murrell_at_auckland.ac.nz>
Date: Wed 01 Jun 2005 - 09:58:58 EST

Hi

Gabor Grothendieck wrote:

> On 5/31/05, Paul Murrell <p.murrell@auckland.ac.nz> wrote:
> 

>>Hi
>>
>>
>>Gabor Grothendieck wrote:
>>
>>>I am setting up base plots -- one in viewport A and and one in B. This part
>>>works fine. But if I go back to A after having done B and add
>>>horizontal lines it seems
>>>to not use the correct coordinates. How do I tell it to resume using A's
>>>coordinates? I am already using par(fig = gridFIG()) but it seems that that's
>>>not enough to reestablish them. What happens is that when I go back to
>>>A it draws the horizontal lines as if its relative to B's coordinates
>>>rather than
>>>restablishing A's coordinates. As a result the horizontal lines are
>>>drawn near the
>>>bottom of the graph instead of at the correct heights. Try running the code
>>>below to see what I mean.
>>>
>>>I have also tried to use baseViewports with this but did not have any
>>>success.
>>>
>>>How do I modify this example so that the horizontal red lines come out
>>>at the appropriate levels? Note that this is just an example and in
>>>the future I will want to have multiple viewports each with a base plot and
>>>add arbitrary additional line or point plots to them so the solution needs
>>>to be sufficiently general that I can so generalize it.
>>>
>>>Thanks.
>>>
>>>
>>>library(gridBase)
>>>
>>>opar <- par(no.readonly = TRUE)
>>>grid.newpage()
>>>
>>># two columns, one row
>>>unit. <- unit(c(1,1), c("null","null"))
>>>pushViewport(viewport(layout = grid.layout(1, 2, widths = unit.)))
>>>
>>># draw green graph in first column (viewport A)
>>>pushViewport(viewport(layout.pos.col = 1, name = "A"))
>>>par(fig = gridFIG()); par(new = TRUE)
>>>plot(1:10, col = "green", pch = 20)
>>>upViewport(1)
>>>
>>># draw purple graph in second column (viewport B)
>>>pushViewport(viewport(layout.pos.col = 2, name = "B"))
>>>par(fig = gridFIG()); par(new = TRUE)
>>>plot(1:100, col = "purple", pch = 18)
>>>upViewport()
>>>
>>># go back to A and add horizontal grid lines
>>>seekViewport("A")
>>>par(fig = gridFIG())
>>>abline(h=1:10, col = "red") #### THESE DO NOT GET DRAWN AS EXPECTED
>>>popViewport()
>>>
>>># go back to B and add vertical grid lines
>>>seekViewport("B")
>>>par(fig = gridFIG())
>>>abline(v=1:10, col = "red")
>>>popViewport()
>>>par(opar)
>>
>>
>>The base, or "traditional", graphics system only records the *current*
>>plotting coordinates; it does not retain a memory of previous plotting
>>coordinates. What your example does is *reposition* the plotting
>>region, but to do what you want you would have to recreate the plotting
>>coordinates of the first plot. This is possible (at least in simple
>>cases like the above), as shown below. However, perhaps a better
>>approach would be to use a combination of grid and lattice plots, where
>>the coordinate systems are retained and don't need to be recreated. An
>>example of this approach is given at the end.
>>
>>#######
>># Modified example using gridBase
>>#######
>>library(gridBase)
>>
>>opar <- par(no.readonly = TRUE)
>>grid.newpage()
>>
>># two columns, one row
>>unit. <- unit(c(1,1), c("null","null"))
>>pushViewport(viewport(layout = grid.layout(1, 2, widths = unit.)))
>>
>># draw green graph in first column (viewport A)
>>pushViewport(viewport(layout.pos.col = 1, name = "A"))
>>par(fig = gridFIG()); par(new = TRUE)
>>plot(1:10, col = "green", pch = 20)
>>upViewport(1)
>>
>># draw purple graph in second column (viewport B)
>>pushViewport(viewport(layout.pos.col = 2, name = "B"))
>>par(fig = gridFIG()); par(new = TRUE)
>>plot(1:100, col = "purple", pch = 18)
>>upViewport()
>>
>># go back to A and add horizontal grid lines
>>seekViewport("A")
>>par(fig = gridFIG()); par(new=TRUE) #### extra par(new=TRUE)
>>plot(1:10, type="n", axes=FALSE, ann=FALSE) #### RESET PLOT A AXES
>>abline(h=1:10, col = "red")
>>popViewport()
>>
>># go back to B and add vertical grid lines
>>seekViewport("B")
>>par(fig = gridFIG()); par(new=TRUE) #### extra par(new=TRUE)
>>plot(1:100, type="n", axes=FALSE, ann=FALSE) #### RESET PLOT B AXES
>>abline(v=1:10, col = "red")
>>popViewport()
>>par(opar)
>>
>>
>>#######
>># Similar result but using grid and lattice
>>#######
>>library(grid)
>>library(lattice)
>>
>>grid.newpage()
>>
>># two columns, one row
>>unit. <- unit(c(1,1), c("null","null"))
>>pushViewport(viewport(layout = grid.layout(1, 2, widths = unit.)))
>>
>># draw green graph in first column (viewport A)
>>pushViewport(viewport(layout.pos.col = 1, name = "A"))
>># lattice plot instead of base plot
>>p1 <- xyplot(1:10 ~ 1:10, col="green", pch=20)
>># prefix important so I can refer to it later
>>print(p1, newpage=FALSE, prefix="plotA")
>>upViewport(1)
>>
>># draw purple graph in second column (viewport B)
>>pushViewport(viewport(layout.pos.col = 2, name = "B"))
>>p2 <- xyplot(1:100 ~ 1:100, col="purple", pch=18)
>>print(p2, newpage=FALSE, prefix="plotB")
>>upViewport()
>>
>># go back to A and add horizontal grid lines
>>seekViewport(trellis.vpname("panel", 1, 1, prefix="plotA"))
>># I'm working on a grid.abline() ...
>>grid.segments(x0=0, x1=1,
>> y0=unit(1:10, "native"),
>> y1=unit(1:10, "native"),
>> gp=gpar(col="red"))
>>
>># go back to B and add vertical grid lines
>>seekViewport(trellis.vpname("panel", 1, 1, prefix="plotB"))
>>grid.segments(y0=0, y1=1,
>> x0=unit(1:10, "native"),
>> x1=unit(1:10, "native"),
>> gp=gpar(col="red"))
>>
>>upViewport(0)
>>
>>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/
>>
>>
> 
> 
> Thanks.  I will study that further.  One other question:
> 
> Using layout or mfcol/mfrow (both from base graphics) one can 
> set it up so each new plot goes into a successive cell.  That is one can
> do a traversal of the cells in a layout by just issuing successive
> calls to plot.  Is there something analogous to that in grid?   What I
> am doing right now is to calculate the row and column of the next cell
> and then move to it like this:
> 
>    # mm.row[j] gives the row in the layout of the jth cell
>    # mm.col[j] gives the col in the layout of the jth cell
>    mm <- matrix(seq(nr*nc), nr, nc)
>    mm.row <- c(row(mm))
>    mm.col <- c(col(mm))
> 
>   # go to next cell in the array
>    j <- j + 1 # increment position
>   pushViewport(viewport(layout.pos.row = mm.row[j], layout.pos.col = mm.col[j]))
> 
> Is that how to do it or is there some layout/mfcol-like way?


That is how to do it.

As far as grid is concerned, all viewports are equal and grid has no idea whether a viewport corresponds to a "plot region" or a "margin" or whatever, so grid has no concept of which viewport is the "next" one to use.

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/

______________________________________________
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Received on Wed Jun 01 10:03:10 2005

This archive was generated by hypermail 2.1.8 : Fri 03 Mar 2006 - 03:32:17 EST