[R] Problem going back to a viewport with gridBase

Paul Murrell p.murrell at auckland.ac.nz
Wed Jun 1 01:58:58 CEST 2005


Hi


Gabor Grothendieck wrote:
> On 5/31/05, Paul Murrell <p.murrell at 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 at 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 at stat.auckland.ac.nz
http://www.stat.auckland.ac.nz/~paul/




More information about the R-help mailing list