準備

# 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)