[R] Problem going back to a viewport with gridBase

Gabor Grothendieck ggrothendieck at gmail.com
Wed Jun 1 01:33:43 CEST 2005


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?



Thanks.




More information about the R-help mailing list