[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