ggplot2で複数のプロットをまとめて表示する方法あれこれ

## プロットの準備

``` r
library(ggplot2)
p1 <- qplot(mpg, wt, data = mtcars, colour = cyl)
p2 <- qplot(mpg, data = mtcars, ylab = "count")
p3 <- qplot(mpg, data = mtcars, ylab = "count", geom = "dotplot")
p4 <- ggplot(mtcars, aes(mpg, wt, col = cyl)) + geom_point() + facet_wrap( ~ carb, nrow = 1)
```

## gridExtra

よくあるのが`gridExtra`パッケージの`grid.arrange()`を使う方法。

``` r
#install.packages("gridExtra")
gridExtra::grid.arrange(p1, p2, nrow = 1)
```

![unnamed-chunk-2-1.png](https://qiita-image-store.s3.amazonaws.com/0/109348/93973d49-94e2-783e-c148-aee6ddcf4075.png)

細かい指定もできるが、しなくても適当に並べてくれる。

``` r
gridExtra::grid.arrange(p1, p2, p3, p4)
```

![unnamed-chunk-3-1.png](https://qiita-image-store.s3.amazonaws.com/0/109348/fbcaacab-0f5d-932e-b768-90c38d803a5b.png)

`grid.arrange()`では各グラフの表示領域が若干ずれる場合があり、例えば以下のような場合はy軸を揃えたいと考えるだろう。

``` r
gridExtra::grid.arrange(p2, p3)
```

![unnamed-chunk-4-1.png](https://qiita-image-store.s3.amazonaws.com/0/109348/9501b3ef-2f32-d615-ea05-c825e450419b.png)

これを揃えたい場合は、`ggplotGrob()`でgrobを作成してrbindで並べる。

``` r
g2 <- ggplotGrob(p2)
g3 <- ggplotGrob(p3)
g <- rbind(g2, g3, size = "first")
g$widths = grid::unit.pmax(g2$widths, g3$widths)
plot(g)
```

![unnamed-chunk-5-1.png](https://qiita-image-store.s3.amazonaws.com/0/109348/0e0996ab-6a18-ff56-74be-97563ab34ff3.png)


ただし、後述のggpubrやcowplotパッケージを使用した方がより分かりやすい書き方ができる。

## ggpubr

ggpubr([‘ggplot2’ Based Publication Ready Plots •
ggpubr](http://www.sthda.com/english/rpkgs/ggpubr/index.html))はggplot2に類似の記法であまり細かい調整をせずともpublication-readyなプロットが作成できるパッケージで、複数プロット配置用の関数として`ggarrange()`が用意されている。使い方は`gridExtra::gird.arrange()`とほぼ同じだが、各プロットにラベルをつけられる`labels`等の少し気の利いた引数が用意されている。`ggarrange()`は後述のcowplotパッケージの`plot_grid()`のラッパーである。

``` r
# install.packages("ggpubr")
library(dplyr)
pp1 <- ggpubr::ggscatter(mtcars, "mpg", "wt")
pp2 <- ggpubr::gghistogram(mtcars, "mpg", fill = "gray", color = "white")
pp3 <- mutate(mtcars, cyl = factor(cyl)) %>%
  ggpubr::ggscatter("wt", "mpg", add = "reg.line", conf.int = TRUE, color = "cyl") +
  ggpubr::stat_cor(aes(color = cyl), label.x = 4)
pp4 <- ggpubr::desc_statby(iris, "Sepal.Length", grps = "Species") %>% 
  select(Species, min, max, median) %>%
  ggpubr::ggtexttable(rows = NULL)
ggpubr::ggarrange(pp1, pp2, pp3, pp4, labels = LETTERS)
```

![unnamed-chunk-6-1.png](https://qiita-image-store.s3.amazonaws.com/0/109348/269e663b-f48c-1338-8021-d7391a264f6d.png)

## cowplot

cowplotもpublication-readyなプロットが作成できるパッケージだが、パッケージを読み込んだ時点でggplotのthemeに変更が加わるので(※)、ggplot2の記法そのままでも使える。先程の`ggpubr::ggarrange()`と同様に`cowplot::plot_grid()`も`gridExtra::grid.arrange()`とほぼ同じように使用できる。

``` r
library(cowplot)
pc1 <- ggplot(mpg, aes(x = cty, y = hwy, color = factor(cyl))) +
  geom_point()
pc2 <- ggplot(diamonds, aes(clarity, fill = cut)) + 
  geom_bar() + 
  theme(axis.text.x = element_text(angle = 70, vjust = 0.5))
plot_grid(pc1, pc2)
```

![unnamed-chunk-7-1.png](https://qiita-image-store.s3.amazonaws.com/0/109348/571d05cd-6467-0613-a2a7-703c58296f2e.png)

ところで、グラフの軸を揃えるための引数`align`が用意されている（これは`ggpubr::ggarrange`でも当然使える）。これを使えば`gridExtra::grid.arrange()`では少し面倒だった作業が簡単に行える。

``` r
plot_grid(pc1, pc2, align = "h")
```

![unnamed-chunk-8-1.png](https://qiita-image-store.s3.amazonaws.com/0/109348/bc577f1a-a961-2353-08f8-2003c3ee727b.png)

※今後はこの「パッケージを読み込んだ時点でthemeが置き換わる」という挙動は無くなり、`theme_cowplot()`を明示的に使用する方向で修正が行われている模様。開発版をgithubからインストールしパッケージをロードすると、既にthemeが自動的に置き換わることは無くなっていること、themeを置き換えてしまいたかったら`theme_set(theme_cowplot())`する必要があることを知らせるメッセージが表示される。

## patchwork

この記事を公開したところ…

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">個人的にはpatchworkが神です．<a href="https://t.co/0BX0l1ZrlY">https://t.co/0BX0l1ZrlY</a></p>&mdash; Atsushi (Atusy) (@Atsushi776) <a href="https://twitter.com/Atsushi776/status/1021901083772243968?ref_src=twsrc%5Etfw">2018年7月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ということを教えて頂いた。（何か`+`とかでくっつけられるやつがあったような…）と思いつつ見つけられずモヤモヤしていたので非常にありがたかった。

見つけられないのは情報が少ないせいだ、という気もしたので、READMEを翻訳した。

- [patchworkを使って複数のggplotを組み合わせる - Qiita](https://qiita.com/nozma/items/4512623bea296ccb74ba)

## その他色々

「単に並べる」以外のアレコレについて。

### 複数プロットを複数ページに出力したい

`gridExtra::marrangeGrob`を使うことができる。

``` r
gridExtra::marrangeGrob(list(p1, p2, p3), nrow = 2, ncol = 1)
```

![unnamed-chunk-11-1.png](https://qiita-image-store.s3.amazonaws.com/0/109348/c706900e-78e6-7a97-fedb-8937d6967fe3.png)

![unnamed-chunk-11-2.png](https://qiita-image-store.s3.amazonaws.com/0/109348/a557006b-729d-b682-957c-9f5d665cbfec.png)


また、`ggpubr::ggarrange()`も複数ページ出力に対応している。こちらは`page n of m`のような表示は付かない。

```r
ggpubr::ggarrange(pp1, pp2, pp3, pp4, nrow = 1, ncol = 2)
```

![unnamed-chunk-7-1.png](https://qiita-image-store.s3.amazonaws.com/0/109348/be132745-37f2-61b8-52e9-95e588ea0162.png)

![unnamed-chunk-7-2.png](https://qiita-image-store.s3.amazonaws.com/0/109348/69257b62-cb95-bd77-44af-f462d41cb6af.png)

### プロットの内部にプロットする

`ggplotGrob`でgrobを作成してから`annotation_custom`で配置。

``` r
g <- ggplotGrob(p2)
p1 + annotation_custom(g, xmin = 25, xmax = 35, ymin = 3, ymax = 5)
```

![unnamed-chunk-12-1.png](https://qiita-image-store.s3.amazonaws.com/0/109348/d04bda78-3dcd-2120-9dff-712c09b236d0.png)


## 参考

  - [Arranging multiple grobs on a
    page](https://cran.r-project.org/web/packages/gridExtra/vignettes/arrangeGrob.html)
  - [Laying out multiple plots on a
    page](https://cran.r-project.org/web/packages/egg/vignettes/Ecosystem.html)
  - [‘ggplot2’ Based Publication Ready Plots •
    ggpubr](http://www.sthda.com/english/rpkgs/ggpubr/index.html)
  - [Introduction to
    cowplot](https://cran.r-project.org/web/packages/cowplot/vignettes/introduction.html)