ggplot2パネル表示のメモ
とくに論文書きでは関係する図をパネル状に並べて表示する機会が多い。 ggplot2のfacetファミリーでどうにかできる場合はいいが、そうでないとパネル分けでいつももたつく。 いくつかのパネル作成パッケージを比較して頭の中を整理する。
packages
現行でパネル作成可能なパッケージなうち、以下の4パッケージを試す。
そのほかにもまだいくつかあるが省略。
- grid
- R core
- どのパッケージも内部的にはgrid経由で表示している
viewport
/grid.layout
- gridExtra & gtable
- Arranging multiple grobs on a page | vignette
- Qiitaのhoxo_bさんの記事が詳しい
- 一昔前はこれ一択だったが、積極的に開発されることはもうないだろう、という感じ
- multipanelplot
- Rcookbook
要件
上から順に優先度が高い。
- パネル間で軸位置を一致させられる
- 縦に並んだ2つのパネルでy軸がずれているとがっかりするので
- insetが可能
- 図の中に小さい図を書くことがままあるので
- パネルへのラベル付記
- Fig. 1aと本文で触れるので
- あれば少し便利くらい
- 凡例を共有できる
- あれば少し便利くらい
各パッケージの仕様を比較する。
packages | adjust_axes | add_inset | label_panels | share_legend |
---|---|---|---|---|
base (ggplot2+gridExtra) | - | annotation_custom() | - | - |
cowplot | plot_grid(…, align = “hv”) | draw_plot() | plot_grid(…, labels), draw_plot_label() | - |
patchwork | default | - | - | - |
egg | default | - | ggarrange(…, labels) | - |
ggpubr | ggarrange(…, align = “hv”) | - | ggarrange(…, labels) | ggarrange(…, common.legend) |
試用
下準備
結合するパネルをggplot2で作る。 散布図 + inset用2次元確率密度 + 周辺分布を準備。
set.seed(2018070001)
dt <- sample_n(diamonds, 200)
scat <-
ggplot(dt, aes(carat, price, fill = cut)) +
geom_point(shape = 21, col = "grey") +
theme(legend.position = c(.1, .9), legend.justification = c(0, 1))
dens_carat <-
ggplot(dt, aes(carat, fill = cut)) +
geom_density(position = "identity", alpha = .5) +
theme(axis.title.x = element_blank(), axis.ticks.x = element_blank(), axis.text.x = element_blank())
dens_price <-
ggplot(dt, aes(price, fill = cut)) +
geom_density(position = "identity", alpha = .5) +
theme(axis.title.y = element_blank(), axis.ticks.y = element_blank(), axis.text.y = element_blank()) +
coord_flip()
dens_2d <-
ggplot(dt, aes(carat, price)) +
geom_density2d(col = "black")
cowplot
- Introduction to cowplot | vignette
- 進化生物学系の研究室 (Wilke lab) が管理者
- パッケージ読み込み時に
theme_cowplot()
を強制theme_classic
をベースに背景を透過にしてあるため重ね書きに適している
- 以下の利点があるため、図の保存には
ggsave
の代わりにsave_plot
を使うのがよいとある- cowplot用に調整済みのサイズ
- 個別に作った図を
plot_grid
で並べて保存するときに適した仕様らしい - アスペクト比の調節が容易
packageVersion("cowplot")
cowplot::plot_grid(dens_carat + guides(fill = F), # (1, 1)
NULL, # (1, 2)
scat, # (2, 1)
dens_price + guides(fill = F), # (2, 2)
nrow = 2, align = "hv",
rel_widths = c(.8, .2), rel_heights = c(.2, .8),
labels = c("a", NA, "b", "c"), label_x = .1, label_y = .95) +
cowplot::draw_plot(dens_2d + cowplot::theme_cowplot(), x = .45, y = .05, width = .3, height = .3)
## [1] '0.9.2'
- 軸位置合わせ:
plot_grid(..., align = c("h", "v", "hv"))
- inset:
draw_plot
- label: デフォルトで左上
- legend: 完全に事前設定
patchwork
- The Composer of ggplots | README
- gganimateなどのthomasp85氏が管理者
- 二項演算子を多用してネストしたパネルわけが可能
- レイアウトの変更が簡単でスピーディ
- 現行で明らかにバグ (Plot assembly fails on minimal plots) がある
plot_layout(..., guides)
がバグっているような気がする
library(patchwork)
packageVersion("patchwork")
dens_carat + guides(fill = F) +
patchwork::plot_spacer() +
scat + ggplot2::annotation_custom(grob = ggplotGrob(dens_2d + theme_minimal()), xmin = 1.5, xmax = 2.5, ymin = 0, ymax = 8000) +
dens_price + guides(fill = F) +
plot_layout(ncol = 2, heights = c(.2, .8), widths = c(.8, .2))
## [1] '0.0.1'
挙動が怪しい。 凡例を消すと動く。
dens_carat + guides(fill = F) +
patchwork::plot_spacer() +
scat + ggplot2::annotation_custom(grob = ggplotGrob(dens_2d + theme_minimal()), xmin = 1.5, xmax = 2.5, ymin = 0, ymax = 8000) + guides(fill = F) + # legendを消すと動く, legend.position = "right"なんかでも動く
dens_price + guides(fill = F) +
plot_layout(ncol = 2, heights = c(.2, .8), widths = c(.8, .2))
- 軸位置合わせ: デフォルトで揃っている
- inset: なし (
ggplo2::annotation_custom
で処理)ggplo2::annotation_custom
であとづけ不可?
- label: なし
- legend: 完全に事前設定
- 備考: バグ多し
egg
- (fragile) extensions for ggplot2 | README
- gridExtraのBaptiste氏が管理者
- ggplotオブジェクトをプロット部と周辺部 (軸・タイトルなど) からなる3x3の要素に分割して並べる
scat_with_inset <-
scat +
ggplot2::annotation_custom(grob = ggplotGrob(dens_2d + theme_minimal()),
xmin = 1.5, xmax = 2.5, ymin = 0, ymax = 8000)
egg::ggarrange(dens_carat + guides(fill = F), # (1, 1)
ggplot() + theme_minimal(), # (1, 2)
scat_with_inset, # (2, 1)
dens_price + guides(fill = F), # (2, 2)
nrow = 2,
widths = c(.8, .2), heights = c(.2, .8),
labels = c("a", "", "b", "c"),
label.args = list(gp = grid::gpar(font = 1),
x = unit(1, "line"),
hjust = 0))
- 軸位置合わせ: デフォルトで揃っている
- inset: なし
ggplo2::annotation_custom
であとづけ不可?
- label: デフォルトで左上にボールドイタリック
- legend: 完全に事前設定
ggpubr
- ggpubr: ‘ggplot2’ Based Publication Ready Plots
- バイオ系研究者のkassambara氏が管理者
- publication readyな図を作るために、という謳い文句
- 各種geomに対応したワンライナー (e.g.
ggbarplot
) がある- 独自のエコシステムを作り上げている感じ
packageVersion("ggpubr")
ggpubr::ggarrange(dens_carat, # (1, 1)
NULL, # (1, 2)
scat, # (2, 1)
dens_price, # (2, 2)
nrow = 2, ncol = 2, align = "hv",
widths = c(.8, .2), heights = c(.2, .8),
labels = c("a", NA, "b", "c"),
common.legend = TRUE) +
ggplot2::annotation_custom(grob = ggplotGrob(dens_2d + theme_minimal()),
xmin = .45, xmax = .75, ymin = .05, ymax = .35)
## [1] '0.1.6'
- 軸位置合わせ:
ggarrange(..., align = c("h", "v", "hv"))
- inset: なし (
ggplo2::annotation_custom
で事後処理可能) - label: デフォルトで左上
- legend: 共有あり
- プロット領域外の上下左右に配置
- 備考:
nrow
・ncol
とも指定しないと動作しない
雑感
patchwork以外の使い勝手はさほど変わらない。 開発者的に主流になりそうなeggに乗っておいて、patchworkを様子見する。 labelの位置はどのパッケージでも微調整が必要そうなので、annotateでぱぱっと書いた方が楽かもしれない。
参考ページ
- GitHub repositories
- vignettes etc.
Session Info
devtools::session_info()
## setting value
## version R version 3.5.0 (2018-04-23)
## system x86_64, darwin15.6.0
## ui X11
## language (EN)
## collate en_US.UTF-8
## tz Australia/Brisbane
## date 2018-07-21
##
## package * version date source
## assertthat 0.2.0 2017-04-11 CRAN (R 3.5.0)
## backports 1.1.2 2017-12-13 CRAN (R 3.5.0)
## base * 3.5.0 2018-04-24 local
## bindr 0.1.1 2018-03-13 CRAN (R 3.5.0)
## bindrcpp 0.2.2 2018-03-29 CRAN (R 3.5.0)
## blogdown 0.6 2018-04-18 CRAN (R 3.5.0)
## bookdown 0.7 2018-02-18 CRAN (R 3.5.0)
## broom * 0.4.4.9000 2018-06-21 Github (tidyverse/broom@2721de4)
## cellranger 1.1.0 2016-07-27 CRAN (R 3.5.0)
## cli 1.0.0 2017-11-05 CRAN (R 3.5.0)
## colorspace 1.3-2 2016-12-14 CRAN (R 3.5.0)
## compiler 3.5.0 2018-04-24 local
## cowplot 0.9.2 2017-12-17 CRAN (R 3.5.0)
## crayon 1.3.4 2017-09-16 CRAN (R 3.5.0)
## datasets * 3.5.0 2018-04-24 local
## devtools * 1.13.5 2018-02-18 CRAN (R 3.5.0)
## digest 0.6.15 2018-01-28 CRAN (R 3.5.0)
## dplyr * 0.7.5 2018-05-19 CRAN (R 3.5.0)
## egg 0.4.0 2018-06-17 CRAN (R 3.5.0)
## evaluate 0.10.1 2017-06-24 CRAN (R 3.5.0)
## forcats * 0.3.0 2018-02-19 CRAN (R 3.5.0)
## ggplot2 * 3.0.0.9000 2018-07-16 Github (hadley/ggplot2@79e8b45)
## ggpubr 0.1.6 2017-11-14 CRAN (R 3.5.0)
## glue 1.2.0 2017-10-29 CRAN (R 3.5.0)
## graphics * 3.5.0 2018-04-24 local
## grDevices * 3.5.0 2018-04-24 local
## grid 3.5.0 2018-04-24 local
## gridExtra 2.3 2017-09-09 CRAN (R 3.5.0)
## gtable 0.2.0 2016-02-26 CRAN (R 3.5.0)
## haven 1.1.1 2018-01-18 CRAN (R 3.5.0)
## highr 0.6 2016-05-09 CRAN (R 3.5.0)
## hms 0.4.2 2018-03-10 CRAN (R 3.5.0)
## htmltools 0.3.6 2017-04-28 CRAN (R 3.5.0)
## httr 1.3.1 2017-08-20 CRAN (R 3.5.0)
## jsonlite 1.5 2017-06-01 CRAN (R 3.5.0)
## knitr * 1.20 2018-02-20 CRAN (R 3.5.0)
## labeling 0.3 2014-08-23 CRAN (R 3.5.0)
## lattice 0.20-35 2017-03-25 CRAN (R 3.5.0)
## lazyeval 0.2.1 2017-10-29 CRAN (R 3.5.0)
## lubridate * 1.7.4 2018-04-11 CRAN (R 3.5.0)
## magrittr * 1.5 2014-11-22 CRAN (R 3.5.0)
## MASS * 7.3-49 2018-02-23 CRAN (R 3.5.0)
## memoise 1.1.0 2017-04-21 CRAN (R 3.5.0)
## methods * 3.5.0 2018-04-24 local
## modelr 0.1.2 2018-05-11 cran (@0.1.2)
## munsell 0.4.3 2016-02-13 CRAN (R 3.5.0)
## nlme 3.1-137 2018-04-07 CRAN (R 3.5.0)
## patchwork * 0.0.1 2018-07-16 Github (thomasp85/patchwork@7fb35b1)
## pillar 1.2.3 2018-05-25 cran (@1.2.3)
## pkgconfig 2.0.1 2017-03-21 CRAN (R 3.5.0)
## plyr 1.8.4 2016-06-08 CRAN (R 3.5.0)
## purrr * 0.2.5 2018-05-29 CRAN (R 3.5.0)
## R6 2.2.2 2017-06-17 CRAN (R 3.5.0)
## Rcpp 0.12.17 2018-05-18 cran (@0.12.17)
## readr * 1.1.1 2017-05-16 CRAN (R 3.5.0)
## readxl 1.1.0 2018-04-20 CRAN (R 3.5.0)
## reshape2 1.4.3 2017-12-11 CRAN (R 3.5.0)
## rlang 0.2.1 2018-05-30 cran (@0.2.1)
## rmarkdown 1.10 2018-06-11 cran (@1.10)
## rprojroot 1.3-2 2018-01-03 CRAN (R 3.5.0)
## rstudioapi 0.7 2017-09-07 CRAN (R 3.5.0)
## rvest 0.3.2 2016-06-17 CRAN (R 3.5.0)
## scales 0.5.0 2017-08-24 CRAN (R 3.5.0)
## stats * 3.5.0 2018-04-24 local
## stringi 1.2.3 2018-06-12 cran (@1.2.3)
## stringr * 1.3.1 2018-05-10 cran (@1.3.1)
## tibble * 1.4.2 2018-01-22 CRAN (R 3.5.0)
## tidyr * 0.8.1 2018-05-18 cran (@0.8.1)
## tidyselect 0.2.4 2018-02-26 CRAN (R 3.5.0)
## tidyverse * 1.2.1 2017-11-14 CRAN (R 3.5.0)
## tools 3.5.0 2018-04-24 local
## utils * 3.5.0 2018-04-24 local
## viridisLite 0.3.0 2018-02-01 CRAN (R 3.5.0)
## withr 2.1.2 2018-03-15 CRAN (R 3.5.0)
## xfun 0.1 2018-01-22 CRAN (R 3.5.0)
## xml2 1.2.0 2018-01-24 CRAN (R 3.5.0)
## yaml 2.1.19 2018-05-01 cran (@2.1.19)