motivation
- layout multiple ggplots in one page, like subplot function in matlab simply using {grid} package.
library(tidyverse, quietly=TRUE)
library(grid)
define my_subplot
my_subplot <- function(nrow=3, ncol=1,
height=7, width=7,
ggs) {
# height and width are in unit inch
# ggs: ggplot objects wrapped as list
# order of ggs is like matrix(1:length(ggs), nrow, ncol)
# todo: spanning
my_layout <- grid.layout(nrow, ncol,
heights=unit(rep(height, nrow)/nrow,
rep("inch", nrow)),
widths=unit(rep(width, ncol)/ncol,
rep("inch", ncol)))
fg <- frameGrob(my_layout)
n <- length(ggs)
for (i in 1:n) {
my_row <- ifelse(i %% nrow == 0, nrow, i %% nrow)
my_col <- ifelse(i %% nrow == 0, i %/% nrow, (i %/% nrow) + 1)
fg <- placeGrob(fg,
ggplotGrob(ggs[[i]]),
row=my_row, col=my_col)
}
fg
}
prepare three ggplots
d <- tibble(t=1:100, y=abs(rnorm(100)))
g1 <- ggplot(d) + geom_point(aes(t, y))
g2 <- ggplot(d) + geom_line(aes(t, y))
g3 <- g1 + geom_line(aes(t, y))
g1

g2

g3

three plots in one page using my_subplot
grid.newpage()
grid.draw(
my_subplot(
3, 1,
3.5, 6.5,
ggs=list(g1, g2, g3)
))

another layout setting
grid.newpage()
grid.draw(
my_subplot(
3, 2,
3.5, 6.5,
ggs=list(g1, g2, g3, g1, g2, g3)
))

references
- Murrell, P. (2005). R graphics. Chapman and Hall/CRC.
- Murrell, P. (2009). R graphics. Wiley Interdisciplinary Reviews: Computational Statistics, 1(2), 216-220.
- Wickham, H., & Grolemund, G. (2016). R for data science: import, tidy, transform, visualize, and model data. ” O’Reilly Media, Inc.”.
LS0tCnRpdGxlOiAibXVsdGlwbGUgZ2dwbG90cyBpbiBvbmUgcGFnZSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCiMgbW90aXZhdGlvbgotIGxheW91dCBtdWx0aXBsZSBnZ3Bsb3RzIGluIG9uZSBwYWdlLCBsaWtlIHN1YnBsb3QgZnVuY3Rpb24gaW4gbWF0bGFiIHNpbXBseSB1c2luZyB7Z3JpZH0gcGFja2FnZS4KCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UsIHF1aWV0bHk9VFJVRSkKbGlicmFyeShncmlkKSAKYGBgCgojIGRlZmluZSBteV9zdWJwbG90CgpgYGB7cn0KbXlfc3VicGxvdCA8LSBmdW5jdGlvbihucm93PTMsIG5jb2w9MSwgCiAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0PTcsIHdpZHRoPTcsCiAgICAgICAgICAgICAgICAgICAgICAgZ2dzKSB7CiAgIyBoZWlnaHQgYW5kIHdpZHRoIGFyZSBpbiB1bml0IGluY2gKICAjIGdnczogZ2dwbG90IG9iamVjdHMgd3JhcHBlZCBhcyBsaXN0CiAgIyBvcmRlciBvZiBnZ3MgaXMgbGlrZSBtYXRyaXgoMTpsZW5ndGgoZ2dzKSwgbnJvdywgbmNvbCkKICAjIHRvZG86IHNwYW5uaW5nCiAgbXlfbGF5b3V0IDwtIGdyaWQubGF5b3V0KG5yb3csIG5jb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodHM9dW5pdChyZXAoaGVpZ2h0LCBucm93KS9ucm93LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcCgiaW5jaCIsIG5yb3cpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhzPXVuaXQocmVwKHdpZHRoLCBuY29sKS9uY29sLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKCJpbmNoIiwgbmNvbCkpKQogIAogIGZnIDwtIGZyYW1lR3JvYihteV9sYXlvdXQpCiAgbiA8LSBsZW5ndGgoZ2dzKQogIGZvciAoaSBpbiAxOm4pIHsKICAgIG15X3JvdyA8LSBpZmVsc2UoaSAlJSBucm93ID09IDAsIG5yb3csIGkgJSUgbnJvdykKICAgIG15X2NvbCA8LSBpZmVsc2UoaSAlJSBucm93ID09IDAsIGkgJS8lIG5yb3csIChpICUvJSBucm93KSArIDEpCiAgICBmZyA8LSBwbGFjZUdyb2IoZmcsIAogICAgICAgICAgICAgICAgICAgIGdncGxvdEdyb2IoZ2dzW1tpXV0pLAogICAgICAgICAgICAgICAgICAgIHJvdz1teV9yb3csIGNvbD1teV9jb2wpCiAgfQogIGZnCn0KYGBgCgojIHByZXBhcmUgdGhyZWUgZ2dwbG90cwpgYGB7cn0KZCA8LSB0aWJibGUodD0xOjEwMCwgeT1hYnMocm5vcm0oMTAwKSkpCmcxIDwtIGdncGxvdChkKSArIGdlb21fcG9pbnQoYWVzKHQsIHkpKQpnMiA8LSBnZ3Bsb3QoZCkgKyBnZW9tX2xpbmUoYWVzKHQsIHkpKQpnMyA8LSBnMSArIGdlb21fbGluZShhZXModCwgeSkpCgpnMQpnMgpnMwpgYGAKCiMgdGhyZWUgcGxvdHMgaW4gb25lIHBhZ2UgdXNpbmcgbXlfc3VicGxvdApgYGB7cn0KZ3JpZC5uZXdwYWdlKCkKZ3JpZC5kcmF3KAogIG15X3N1YnBsb3QoCiAgICAzLCAxLAogICAgMy41LCA2LjUsCiAgICBnZ3M9bGlzdChnMSwgZzIsIGczKQogICkpCmBgYAoKIyBhbm90aGVyIGxheW91dCBzZXR0aW5nCmBgYHtyfQpncmlkLm5ld3BhZ2UoKQpncmlkLmRyYXcoCiAgbXlfc3VicGxvdCgKICAgIDMsIDIsCiAgICAzLjUsIDYuNSwKICAgIGdncz1saXN0KGcxLCBnMiwgZzMsIGcxLCBnMiwgZzMpCiAgKSkKYGBgCgoKCiMgcmVmZXJlbmNlcwotIE11cnJlbGwsIFAuICgyMDA1KS4gUiBncmFwaGljcy4gQ2hhcG1hbiBhbmQgSGFsbC9DUkMuCi0gTXVycmVsbCwgUC4gKDIwMDkpLiBSIGdyYXBoaWNzLiBXaWxleSBJbnRlcmRpc2NpcGxpbmFyeSBSZXZpZXdzOiBDb21wdXRhdGlvbmFsIFN0YXRpc3RpY3MsIDEoMiksIDIxNi0yMjAuCi0gV2lja2hhbSwgSC4sICYgR3JvbGVtdW5kLCBHLiAoMjAxNikuIFIgZm9yIGRhdGEgc2NpZW5jZTogaW1wb3J0LCB0aWR5LCB0cmFuc2Zvcm0sIHZpc3VhbGl6ZSwgYW5kIG1vZGVsIGRhdGEuICIgTydSZWlsbHkgTWVkaWEsIEluYy4iLgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo=