# CRAN版はrbind/cbindにちょっとした問題があるのでbaptiste版を使う
#devtools::install_github("baptiste/gtable")
library(gtable)
## Loading required package: grid
library(ggplot2)
# 比較のために
library(gridExtra)
# 便利関数
gg = function(p) ggplot_gtable(ggplot_build(p))
P = function(x) grid::grid.draw(x)
# プロットオブジェクト
p1 = ggplot(mtcars, aes(wt, mpg)) + geom_point()
p2 = ggplot(mtcars, aes(wt*100, mpg*100)) + geom_line()
p3 = ggplot(mtcars, aes(wt*100000, mpg*100000)) + geom_polygon()
# そのgtable
g1 = gg(p1)
g2 = gg(p2)
g3 = gg(p3)
grid.arrangeだと幅が不均一
grid.arrange(p1, p2, p3, nrow=1)
cbindでやる
o = cbind(g1, g2, g3)
o
## TableGrob (6 x 15) "layout": 24 grobs
## z cells name grob
## 1 0 ( 1- 6, 1- 5) background rect[plot.background.rect.36]
## 2 3 ( 3- 3, 3- 3) axis-l absoluteGrob[GRID.absoluteGrob.28]
## 3 1 ( 4- 4, 3- 3) spacer zeroGrob[NULL]
## 4 2 ( 3- 3, 4- 4) panel gTree[GRID.gTree.16]
## 5 4 ( 4- 4, 4- 4) axis-b absoluteGrob[GRID.absoluteGrob.22]
## 6 5 ( 5- 5, 4- 4) xlab text[axis.title.x.text.30]
## 7 6 ( 3- 3, 2- 2) ylab text[axis.title.y.text.32]
## 8 7 ( 2- 2, 4- 4) title text[plot.title.text.34]
## 9 0 ( 1- 6, 6-10) background rect[plot.background.rect.71]
## 10 3 ( 3- 3, 8- 8) axis-l absoluteGrob[GRID.absoluteGrob.63]
## 11 1 ( 4- 4, 8- 8) spacer zeroGrob[NULL]
## 12 2 ( 3- 3, 9- 9) panel gTree[GRID.gTree.51]
## 13 4 ( 4- 4, 9- 9) axis-b absoluteGrob[GRID.absoluteGrob.57]
## 14 5 ( 5- 5, 9- 9) xlab text[axis.title.x.text.65]
## 15 6 ( 3- 3, 7- 7) ylab text[axis.title.y.text.67]
## 16 7 ( 2- 2, 9- 9) title text[plot.title.text.69]
## 17 0 ( 1- 6,11-15) background rect[plot.background.rect.108]
## 18 3 ( 3- 3,13-13) axis-l absoluteGrob[GRID.absoluteGrob.100]
## 19 1 ( 4- 4,13-13) spacer zeroGrob[NULL]
## 20 2 ( 3- 3,14-14) panel gTree[GRID.gTree.88]
## 21 4 ( 4- 4,14-14) axis-b absoluteGrob[GRID.absoluteGrob.94]
## 22 5 ( 5- 5,14-14) xlab text[axis.title.x.text.102]
## 23 6 ( 3- 3,12-12) ylab text[axis.title.y.text.104]
## 24 7 ( 2- 2,14-14) title text[plot.title.text.106]
# パネルの幅が全て1nullなので等幅になる
o$widths
## [1] 0.5lines 1grobwidth+0.5lines
## [3] sum(1grobwidth, 0.15cm+0.1cm) 1null
## [5] 1lines 0.5lines
## [7] 1grobwidth+0.5lines sum(1grobwidth, 0.15cm+0.1cm)
## [9] 1null 1lines
## [11] 0.5lines 1grobwidth+0.5lines
## [13] sum(1grobwidth, 0.15cm+0.1cm) 1null
## [15] 1lines
P(o)
# プロットオブジェクト
p1 = ggplot(mtcars, aes(wt, mpg, colour = factor(am))) + geom_point() + theme(legend.position = "none")
p2 = ggplot(mtcars, aes(wt*100, mpg*100, colour = factor(am))) + geom_line() + theme(legend.position = "none")
p3 = ggplot(mtcars, aes(wt*100000, mpg*100000, colour = factor(am))) + geom_polygon()
# そのgtable
g1 = gg(p1)
g2 = gg(p2)
g3 = gg(p3)
grid.arrangeだと幅が不均一・・・残念すぎる
grid.arrange(p1, p2, p3, nrow=1)
cbindでやる。幅揃う
o = cbind(g1, g2, g3)
P(o)
# プロットオブジェクト
p1 = ggplot(mtcars, aes(wt, mpg, colour = factor(am))) + geom_point() + theme(legend.position = "none")
p2 = ggplot(mtcars, aes(wt*100, mpg*100, colour = factor(am))) + geom_line() + theme(legend.position = "none")
p3 = ggplot(mtcars, aes(wt*100000, mpg*100000, colour = factor(am))) + geom_polygon() + theme(legend.position = "top")
# そのgtable
g1 = gg(p1)
g2 = gg(p2)
g3 = gg(p3)
grid.arrangeだと幅が不均一・・・ワロス
grid.arrange(p1, p2, p3, nrow=1)
cbindでやると、縦の要素数が違うのでエラー
o = cbind(g1, g2, g3)
## Error: nrow(x) == nrow(y) は TRUE ではありません
なので、凡例のgtableを取り出して、プロットのgtableから凡例を削除
# プロットオブジェクト
p1 = ggplot(mtcars, aes(wt, mpg, colour = factor(am))) + geom_point() + theme(legend.position = "none")
p2 = ggplot(mtcars, aes(wt*100, mpg*100, colour = factor(am))) + geom_line() + theme(legend.position = "none")
p3 = ggplot(mtcars, aes(wt*100000, mpg*100000, colour = factor(am))) + geom_polygon() + theme(legend.position = "top")
# そのgtable
g1 = gg(p1)
g2 = gg(p2)
g3 = gg(p3)
gL = g3[3,] # 凡例だけ取り出す
g3 = g3[-3,] # 凡例を削除
grid.arrangeで縦に並べてみる・・・はいはい、ワロスワロス
o = cbind(g1, g2, g3)
grid.arrange(gL, o)
viewportで適当に調整、出来るけどめっちゃ面倒
pushViewport(viewport(layout=grid.layout(2, 1,heights=unit(c(0.1, 0.9), "null"))))
pushViewport(viewport(layout.pos.col=1, layout.pos.row=1))
P(gL)
popViewport()
pushViewport(viewport(layout.pos.col=1, layout.pos.row=2))
P(o)
popViewport()
grid.arrange(gL, o, heights = unit(c(0.1, 0.9), "null"))
おぉ、素晴らしい!!