Helske Satu
2014-Nov-26 11:16 UTC
[R] Using grid.layout inside grid.layout with grid package: naming of the viewports affects plotting
R version 3.1.1 (2014-07-10)
Platform: i386-w64-mingw32/i386 (32-bit)
locale:
[1] C
attached base packages:
[1] grid stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] tools_3.1.1
I have a plotting function to produce plots with stacked plots (for simplicity,
here two rectangles).
library(grid)
stackedplot <- function(main=""){
top.vp <- viewport(
layout=grid.layout(2, 1))
p1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="plot1")
p2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="plot2")
splot <- vpTree(top.vp, vpList(p1,p2))
pushViewport(splot)
seekViewport("plot1")
grid.rect(width=unit(0.9, "npc"), height=unit(0.9, "npc"))
seekViewport("plot2")
grid.rect(width=unit(0.9, "npc"), height=unit(0.9, "npc"))
}
For creating a 2x2 grid with four stacked plots I tried to use the following
code:
grid.newpage()
multitop.vp <- viewport(layout=grid.layout(2,2))
pl1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="A")
pl2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="B")
pl3 <- viewport(layout.pos.col=2, layout.pos.row=1, name="C")
pl4 <- viewport(layout.pos.col=2, layout.pos.row=2, name="D")
vpall <- vpTree(multitop.vp, vpList(pl1,pl2,pl3,pl4))
pushViewport(vpall)
seekViewport("A")
stackedplot(main="A")
seekViewport("B")
stackedplot(main="B")
seekViewport("C")
stackedplot(main="C")
seekViewport("D")
stackedplot(main="D")
This does not work as all the plots are plotted in the same cell of the grid
(viewport A). However, if I plot them in a reversed order, the plots arrange as
was supposed to: D to D, C to C and so on.
seekViewport("D")
stackedplot(main="D")
seekViewport("C")
stackedplot(main="C")
seekViewport("B")
stackedplot(main="B")
seekViewport("A")
stackedplot(main="A")
I tried with different names and found out that if I plot in reversed
alphabetical order everything works fine. Once I try to plot in a viewport with
a name earlier in alphabetical order, all other plots thereafter are plotted in
the same viewport.
Why is this happening?
Regards,
Satu Helske
[[alternative HTML version deleted]]
Paul Murrell
2014-Nov-27 20:36 UTC
[R] Using grid.layout inside grid.layout with grid package: naming of the viewports affects plotting
Hi
The essence of your problem is that seekViewport() is much more
ambiguous than downViewport().
Your set up involves creating a hierarchy of viewports four deep, with
eight viewport paths (vpPaths) in total ...
vp1::A::vp2::plot1
::plot2
::B::vp3::plot1
::plot2
::C::vp4::plot1
::plot2
::D::vp5::plot1
::plot2
... and an important feature of that set of vpPaths is that the viewport
name "plot1" (and "plot2") occurs more than once.
That is not necessarily a problem because you can distinguish between
the different instances of "plot1" with complete paths, like this ...
downViewport("vp1::B::vp3::plot1")
... or by navigating part way down the tree of viewports first to a
point where there is only one "plot1" viewport below it ...
downViewport("B")
downViewport("plot1")
However, seekViewport("plot1") does NOT do either of those things. It
does ...
upViewport(0) # go right up to the ROOT viewport
downViewport("plot1")
... and that will just find the first "plot1" match, which is the one
below viewport "A".
The seekViewport() function should not therefore be relied on in
non-interactive settings. In fact, if you are writing code for general
use, you should probably be much more disciplined about how you navigate
between your viewports and make use of upViewport() and unambiguous
downViewport() calls so that you know which viewport you will end up in.
The code below demonstrates a more disciplined version of your
viewport set up ...
library(grid)
stackedplot <- function(main=""){
top.vp <- viewport(
layout=grid.layout(2, 1))
p1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="plot1")
p2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="plot2")
splot <- vpTree(top.vp, vpList(p1,p2))
pushViewport(splot)
upViewport()
downViewport("plot1")
grid.rect(width=unit(0.9, "npc"), height=unit(0.9,
"npc"))
grid.text(paste(main, 1))
upViewport()
downViewport("plot2")
grid.rect(width=unit(0.9, "npc"), height=unit(0.9,
"npc"))
grid.text(paste(main, 1))
upViewport(2)
}
grid.newpage()
multitop.vp <- viewport(layout=grid.layout(2,2))
pl1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="A")
pl2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="B")
pl3 <- viewport(layout.pos.col=2, layout.pos.row=1, name="C")
pl4 <- viewport(layout.pos.col=2, layout.pos.row=2, name="D")
vpall <- vpTree(multitop.vp, vpList(pl1,pl2,pl3,pl4))
pushViewport(vpall)
upViewport()
downViewport("A")
stackedplot(main="A")
upViewport()
downViewport("B")
stackedplot(main="B")
upViewport()
downViewport("C")
stackedplot(main="C")
upViewport()
downViewport("D")
stackedplot(main="D")
upViewport(2)
Hope that helps
Paul
On 11/27/14 00:16, Helske Satu wrote:> R version 3.1.1 (2014-07-10)
> Platform: i386-w64-mingw32/i386 (32-bit)
>
> locale:
> [1] C
>
> attached base packages:
> [1] grid stats graphics grDevices utils datasets methods
base
>
> loaded via a namespace (and not attached):
> [1] tools_3.1.1
>
>
> I have a plotting function to produce plots with stacked plots (for
simplicity, here two rectangles).
>
> library(grid)
> stackedplot <- function(main=""){
> top.vp <- viewport(
> layout=grid.layout(2, 1))
> p1 <- viewport(layout.pos.col=1, layout.pos.row=1,
name="plot1")
> p2 <- viewport(layout.pos.col=1, layout.pos.row=2,
name="plot2")
> splot <- vpTree(top.vp, vpList(p1,p2))
> pushViewport(splot)
> seekViewport("plot1")
> grid.rect(width=unit(0.9, "npc"), height=unit(0.9,
"npc"))
> seekViewport("plot2")
> grid.rect(width=unit(0.9, "npc"), height=unit(0.9,
"npc"))
> }
>
> For creating a 2x2 grid with four stacked plots I tried to use the
following code:
>
> grid.newpage()
> multitop.vp <- viewport(layout=grid.layout(2,2))
> pl1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="A")
> pl2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="B")
> pl3 <- viewport(layout.pos.col=2, layout.pos.row=1, name="C")
> pl4 <- viewport(layout.pos.col=2, layout.pos.row=2, name="D")
> vpall <- vpTree(multitop.vp, vpList(pl1,pl2,pl3,pl4))
> pushViewport(vpall)
> seekViewport("A")
> stackedplot(main="A")
> seekViewport("B")
> stackedplot(main="B")
> seekViewport("C")
> stackedplot(main="C")
> seekViewport("D")
> stackedplot(main="D")
>
> This does not work as all the plots are plotted in the same cell of the
grid (viewport A). However, if I plot them in a reversed order, the plots
arrange as was supposed to: D to D, C to C and so on.
>
> seekViewport("D")
> stackedplot(main="D")
> seekViewport("C")
> stackedplot(main="C")
> seekViewport("B")
> stackedplot(main="B")
> seekViewport("A")
> stackedplot(main="A")
>
> I tried with different names and found out that if I plot in reversed
alphabetical order everything works fine. Once I try to plot in a viewport with
a name earlier in alphabetical order, all other plots thereafter are plotted in
the same viewport.
>
> Why is this happening?
>
> Regards,
> Satu Helske
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
--
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/
Helske Satu
2014-Nov-28 07:22 UTC
[R] Using grid.layout inside grid.layout with grid package: naming of the viewports affects plotting
Hi Paul, Thank you for your illustrative explanation and help with rewriting the code. It works now and, more importantly, I understand what is happening and why. Best regards, Satu>-----Original Message----- >From: Paul Murrell [mailto:paul at stat.auckland.ac.nz] >Sent: 27. marraskuuta 2014 22:37 >To: Helske Satu; r-help at r-project.org >Subject: Re: [R] Using grid.layout inside grid.layout with grid package: naming of >the viewports affects plotting > >Hi > >The essence of your problem is that seekViewport() is much more ambiguous >than downViewport(). > >Your set up involves creating a hierarchy of viewports four deep, with eight >viewport paths (vpPaths) in total ... > >vp1::A::vp2::plot1 > ::plot2 > ::B::vp3::plot1 > ::plot2 > ::C::vp4::plot1 > ::plot2 > ::D::vp5::plot1 > ::plot2 > >... and an important feature of that set of vpPaths is that the viewport name >"plot1" (and "plot2") occurs more than once. > >That is not necessarily a problem because you can distinguish between the >different instances of "plot1" with complete paths, like this ... > >downViewport("vp1::B::vp3::plot1") > >... or by navigating part way down the tree of viewports first to a point where >there is only one "plot1" viewport below it ... > >downViewport("B") >downViewport("plot1") > >However, seekViewport("plot1") does NOT do either of those things. It does ... > >upViewport(0) # go right up to the ROOT viewport >downViewport("plot1") > >... and that will just find the first "plot1" match, which is the one below viewport >"A". > >The seekViewport() function should not therefore be relied on in non-interactive >settings. In fact, if you are writing code for general use, you should probably be >much more disciplined about how you navigate between your viewports and >make use of upViewport() and unambiguous >downViewport() calls so that you know which viewport you will end up in. > The code below demonstrates a more disciplined version of your viewport set >up ... > >library(grid) >stackedplot <- function(main=""){ > top.vp <- viewport( > layout=grid.layout(2, 1)) > p1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="plot1") > p2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="plot2") > splot <- vpTree(top.vp, vpList(p1,p2)) > pushViewport(splot) > upViewport() > downViewport("plot1") > grid.rect(width=unit(0.9, "npc"), height=unit(0.9, "npc")) > grid.text(paste(main, 1)) > upViewport() > downViewport("plot2") > grid.rect(width=unit(0.9, "npc"), height=unit(0.9, "npc")) > grid.text(paste(main, 1)) > upViewport(2) > } > >grid.newpage() >multitop.vp <- viewport(layout=grid.layout(2,2)) >pl1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="A") >pl2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="B") >pl3 <- viewport(layout.pos.col=2, layout.pos.row=1, name="C") >pl4 <- viewport(layout.pos.col=2, layout.pos.row=2, name="D") vpall <- >vpTree(multitop.vp, vpList(pl1,pl2,pl3,pl4)) >pushViewport(vpall) >upViewport() >downViewport("A") >stackedplot(main="A") >upViewport() >downViewport("B") >stackedplot(main="B") >upViewport() >downViewport("C") >stackedplot(main="C") >upViewport() >downViewport("D") >stackedplot(main="D") >upViewport(2) > >Hope that helps > >Paul > >On 11/27/14 00:16, Helske Satu wrote: >> R version 3.1.1 (2014-07-10) >> Platform: i386-w64-mingw32/i386 (32-bit) >> >> locale: >> [1] C >> >> attached base packages: >> [1] grid stats graphics grDevices utils datasets methods base >> >> loaded via a namespace (and not attached): >> [1] tools_3.1.1 >> >> >> I have a plotting function to produce plots with stacked plots (for simplicity, >here two rectangles). >> >> library(grid) >> stackedplot <- function(main=""){ >> top.vp <- viewport( >> layout=grid.layout(2, 1)) >> p1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="plot1") >> p2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="plot2") >> splot <- vpTree(top.vp, vpList(p1,p2)) >> pushViewport(splot) >> seekViewport("plot1") >> grid.rect(width=unit(0.9, "npc"), height=unit(0.9, "npc")) >> seekViewport("plot2") >> grid.rect(width=unit(0.9, "npc"), height=unit(0.9, "npc")) >> } >> >> For creating a 2x2 grid with four stacked plots I tried to use the following code: >> >> grid.newpage() >> multitop.vp <- viewport(layout=grid.layout(2,2)) >> pl1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="A") >> pl2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="B") >> pl3 <- viewport(layout.pos.col=2, layout.pos.row=1, name="C") >> pl4 <- viewport(layout.pos.col=2, layout.pos.row=2, name="D") vpall <- >> vpTree(multitop.vp, vpList(pl1,pl2,pl3,pl4)) >> pushViewport(vpall) >> seekViewport("A") >> stackedplot(main="A") >> seekViewport("B") >> stackedplot(main="B") >> seekViewport("C") >> stackedplot(main="C") >> seekViewport("D") >> stackedplot(main="D") >> >> This does not work as all the plots are plotted in the same cell of the grid >(viewport A). However, if I plot them in a reversed order, the plots arrange as >was supposed to: D to D, C to C and so on. >> >> seekViewport("D") >> stackedplot(main="D") >> seekViewport("C") >> stackedplot(main="C") >> seekViewport("B") >> stackedplot(main="B") >> seekViewport("A") >> stackedplot(main="A") >> >> I tried with different names and found out that if I plot in reversed alphabetical >order everything works fine. Once I try to plot in a viewport with a name earlier >in alphabetical order, all other plots thereafter are plotted in the same viewport. >> >> Why is this happening? >> >> Regards, >> Satu Helske >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide >> http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. >> > >-- >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/