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

From: Gabor Grothendieck <ggrothendieck_at_gmail.com>
Date: Wed 01 Jun 2005 - 09:33:43 EST

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?

Thanks.



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 09:41:38 2005

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