Kevin Wright
2006-Jun-27 20:31 UTC
[R] Mixing grid and base graphics--need help understanding this quirk
My setup: Windows 2000, R 2.3.1 When I start a brand new session of R and paste the code below into R, the graphic device shows "Some text" in the lower left corner. If I paste the code into the command window again, then "Some text" does not appear in the lower left corner. Why is this? require(grid) par(mfrow=c(1,2)) plot(1:10) plot(-10:1) par(mfrow=c(1,1)) pushViewport(viewport(.04, .04, width=stringWidth("Some text"), height=unit(2,"lines"), name="pagenum", gp=gpar(fontsize=10))) grid.text("Some text", gp=gpar(col="gray30"), just=c("left","bottom")) popViewport() Kevin Wright
Paul Murrell
2006-Jun-28 22:46 UTC
[R] Mixing grid and base graphics--need help understanding this quirk
Hi Kevin Wright wrote:> My setup: Windows 2000, R 2.3.1 > > When I start a brand new session of R and paste the code below into R, > the graphic device shows "Some text" in the lower left corner. If I > paste the code into the command window again, then "Some text" does > not appear in the lower left corner. Why is this? > > require(grid) > par(mfrow=c(1,2)) > plot(1:10) > plot(-10:1) > par(mfrow=c(1,1)) > pushViewport(viewport(.04, .04, width=stringWidth("Some text"), > height=unit(2,"lines"), > name="pagenum", gp=gpar(fontsize=10))) > grid.text("Some text", gp=gpar(col="gray30"), > just=c("left","bottom")) > popViewport()Good question! :) Short answer: Traditional and grid graphics are fighting each other for control of the clipping region. Simple fix/workaround: Explicitly set the clipping region for the grid output, like this ... require(grid) par(mfrow=c(1,2)) plot(1:10) plot(-10:1) par(mfrow=c(1,1)) # Requires R >= 2.3.0 grid.clip() pushViewport(viewport(.04, .04, width=stringWidth("Some text"), height=unit(2,"lines"), name="pagenum", gp=gpar(fontsize=10))) grid.text("Some text", gp=gpar(col="gray30"), just=c("left","bottom")) popViewport() Long answer: The first time you run the code, the pushViewport() call is the first grid operation on the graphics device, so some initial grid set up occurs, *including setting the clipping region to the whole device*. The second time you run the code, the pushViewport() call just inherits the current clipping region (which is the one set by the last traditional plot) so the text gets clipped. You can see this effect, with the following code (the text does not even appear the first time because the grid initialisation occurs before the traditional plots) ... require(grid) grid.newpage() par(mfrow=c(1,2)) plot(1:10) plot(-10:1) par(mfrow=c(1,1)) pushViewport(viewport(.04, .04, width=stringWidth("Some text"), height=unit(2,"lines"), name="pagenum", gp=gpar(fontsize=10))) grid.text("Some text", gp=gpar(col="gray30"), just=c("left","bottom")) popViewport() ... so really the problem is that the text should never appear. Interestingly, if you run your original code (text is drawn), then run it again (text is not drawn), then ONLY run the grid part (push, text, pop) the text DOES get drawn! This happens because the popViewport() restores the clipping region of the previous grid viewport (which is the whole device). I need to think a bit more about whether this behaviour can be "fixed", whether it should be fixed, or whether the current "user beware" warning about mixing traditional and grid graphics is sufficient. 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/