Peter Cowan
2008-Aug-06 08:13 UTC
[R] grid layout scaling viewport width based solely on height
Hello all, I'm trying to write a function that produces a main plotting region with several square plots along the right side. Ideally the size of right side plots will scale only with the height of the entire plot, yet never overlap with another secondary plot. The following two snippets get close, however, as I resize the plot horizontally the right side plots (green squares) get smaller whereas I'd like them to remain the same size. It seems the answer lies in setting the layout width for the side plot column in a clever way that I haven't been able to discover. Any suggestions on how to achieve that effect or other improvements to the below code are most welcome. Hopefully, my explanation makes my goal clear. Also note, the real application is a function that will have arbitrary numbers of side plots. Thanks Peter require(grid) grid.newpage() lout1 <- grid.layout(nrow = 1, ncol = 2, widths = unit(c(1, 1/10), c('null', 'snpc')) ) pushViewport(viewport(layout = lout1, w = 0.8, h = 0.8)) pushViewport(viewport(layout.pos.col = 1)) grid.rect() popViewport() pushViewport(viewport(layout.pos.col = 2)) lout2 <- grid.layout(nrow = 10, ncol = 1, heights = unit(1, 'snpc')) pushViewport(viewport(layout = lout2)) for(i in seq(0, 1, length.out = 10)) { pushViewport(viewport(y = i, width = unit(1, 'snpc'), height = unit(1, 'snpc'))) grid.rect(gp = gpar(col = 3)) popViewport() } popViewport() popViewport() popViewport() grid.newpage() lout3 <- grid.layout(nrow = 10, ncol = 11, respect = matrix(c(rep(0, 10 * 10), rep(0, 10 - 1), 1), nrow = 10) ) pushViewport(viewport(layout = lout3, w = 0.8, h = 0.8)) pushViewport(viewport(layout.pos.col = 1:10)) grid.rect() popViewport() pushViewport(viewport(layout.pos.col = 11)) for(i in seq(0, 1, length.out = 10)) { pushViewport(viewport(y = i, width = unit(1, 'snpc'), height = unit(1, 'snpc'))) grid.rect(gp = gpar(col = 3)) popViewport() } popViewport() popViewport()
Paul Murrell
2008-Aug-06 20:40 UTC
[R] grid layout scaling viewport width based solely on height
Hi Peter Cowan wrote:> Hello all, > > I'm trying to write a function that produces a main plotting region > with several square plots along the right side. Ideally the size of > right side plots will scale only with the height of the entire plot, > yet never overlap with another secondary plot. The following two > snippets get close, however, as I resize the plot horizontally the > right side plots (green squares) get smaller whereas I'd like them to > remain the same size. It seems the answer lies in setting the layout > width for the side plot column in a clever way that I haven't been > able to discover. Any suggestions on how to achieve that effect or > other improvements to the below code are most welcome. > > Hopefully, my explanation makes my goal clear. Also note, the real > application is a function that will have arbitrary numbers of side > plots.Sorry, I'm not completely sure what you want to end up with, but do either of the following come close ? # Side plots square and attached to each other # With "tall" plot, get gaps top and bottom # With "wide" plot, get gap on the right lay1 <- grid.layout(1, 2, widths=c(10, 1)) lay2 <- grid.layout(10, 1, respect=TRUE, just="left") # grid.newpage() pushViewport(viewport(width=.8, height=.8, layout=lay1)) grid.rect(gp=gpar(col="grey")) pushViewport(viewport(layout.pos.col=1)) grid.rect(gp=gpar(fill="grey")) popViewport() pushViewport(viewport(layout.pos.col=2, layout=lay2)) for (i in 1:10) { pushViewport(viewport(layout.pos.row=i)) grid.rect(gp=gpar(fill="light grey")) popViewport() } popViewport() # Side plots square and separate from each other # With "tall" plot, get gaps between vertically # With "wide" plot, get gap on the right lay1 <- grid.layout(10, 2, widths=c(10, 1)) # grid.newpage() pushViewport(viewport(width=.8, height=.8, layout=lay1)) grid.rect(gp=gpar(col="grey")) pushViewport(viewport(layout.pos.col=1)) grid.rect(gp=gpar(fill="grey")) popViewport() for (i in 1:10) { pushViewport(viewport(layout.pos.col=2, layout.pos.row=i)) pushViewport(viewport(x=0, width=unit(1, "snpc"), height=unit(1, "snpc"), just="left")) grid.rect(gp=gpar(fill="light grey")) popViewport(2) } Paul> Thanks > > Peter > > require(grid) > grid.newpage() > lout1 <- grid.layout(nrow = 1, ncol = 2, > widths = unit(c(1, 1/10), c('null', 'snpc')) > ) > pushViewport(viewport(layout = lout1, w = 0.8, h = 0.8)) > pushViewport(viewport(layout.pos.col = 1)) > grid.rect() > popViewport() > > pushViewport(viewport(layout.pos.col = 2)) > lout2 <- grid.layout(nrow = 10, ncol = 1, > heights = unit(1, 'snpc')) > pushViewport(viewport(layout = lout2)) > for(i in seq(0, 1, length.out = 10)) { > pushViewport(viewport(y = i, width = unit(1, 'snpc'), > height = unit(1, 'snpc'))) > grid.rect(gp = gpar(col = 3)) > popViewport() > } > popViewport() > popViewport() > popViewport() > > > grid.newpage() > lout3 <- grid.layout(nrow = 10, ncol = 11, > respect = matrix(c(rep(0, 10 * 10), rep(0, 10 - 1), 1), nrow = 10) > ) > pushViewport(viewport(layout = lout3, w = 0.8, h = 0.8)) > pushViewport(viewport(layout.pos.col = 1:10)) > grid.rect() > popViewport() > > pushViewport(viewport(layout.pos.col = 11)) > for(i in seq(0, 1, length.out = 10)) { > pushViewport(viewport(y = i, width = unit(1, 'snpc'), > height = unit(1, 'snpc'))) > grid.rect(gp = gpar(col = 3)) > popViewport() > } > popViewport() > popViewport() > > ______________________________________________ > 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/