par() 関数またはlayout() 関数を使用した、ggplot2 の結合プロット (単一プロット内ではない)[重複]
質問
ggplotsを結合するためにpar()またはlayout()関数を使用することを考えてきました。それらの機能は使えるようになるのでしょうか?
散布図には ggplot をプロットし、ヒストグラムには ggplot をプロットしたいとします。そして、2 つのプロットを (単一のプロットではなく) 結合したいと考えています。該当しますか?
ggplot関数を使用せずに、Rで単純なプロットを試してみました。そしてそれは実際に機能します。
Quick-R のサンプルを次に示します (リンク): http://www.statmethods.net/advgraphs/layout.html
# 4 figures arranged in 2 rows and 2 columns
attach(mtcars)
par(mfrow=c(2,2))
plot(wt,mpg, main="Scatterplot of wt vs. mpg")
plot(wt,disp, main="Scatterplot of wt vs disp")
hist(wt, main="Histogram of wt")
boxplot(wt, main="Boxplot of wt")
# One figure in row 1 and two figures in row 2
attach(mtcars)
layout(matrix(c(1,1,2,3), 2, 2, byrow = TRUE))
hist(wt)
hist(mpg)
hist(disp)
しかし、ggplot を使用してプロットを結合しようとすると、出力が得られません。
解決
library(ggplot2)
library(grid)
vplayout <- function(x, y) viewport(layout.pos.row = x, layout.pos.col = y)
plot1 <- qplot(mtcars,x=wt,y=mpg,geom="point",main="Scatterplot of wt vs. mpg")
plot2 <- qplot(mtcars,x=wt,y=disp,geom="point",main="Scatterplot of wt vs disp")
plot3 <- qplot(wt,data=mtcars)
plot4 <- qplot(wt,mpg,data=mtcars,geom="boxplot")
plot5 <- qplot(wt,data=mtcars)
plot6 <- qplot(mpg,data=mtcars)
plot7 <- qplot(disp,data=mtcars)
# 4 figures arranged in 2 rows and 2 columns
grid.newpage()
pushViewport(viewport(layout = grid.layout(2, 2)))
print(plot1, vp = vplayout(1, 1))
print(plot2, vp = vplayout(1, 2))
print(plot3, vp = vplayout(2, 1))
print(plot4, vp = vplayout(2, 2))
# One figure in row 1 and two figures in row 2
grid.newpage()
pushViewport(viewport(layout = grid.layout(2, 2)))
print(plot5, vp = vplayout(1, 1:2))
print(plot6, vp = vplayout(2, 1))
print(plot7, vp = vplayout(2, 2))
他のヒント
この点でもっと注目されるべきだと私が思うユーティリティは、 layOut
以前の wq
パッケージ(大文字の「O」に注意してください)。それ以来削除されました wq
パッケージなので、以下のコードを追加して名前を変更しました lay_out
典型的な ggplot スタイルと一致します。まるで base::layout
プロットはさまざまなサイズで、行と列にレイアウトできます。それぞれの引数 lay_out
プロット、それをプロットする行インデックス、およびそれをプロットする列インデックスで構成される 3 要素のリストです。
たとえば、@Paul McMurdie のプロットを使用すると、
lay_out(list(plot1, 1, 1),
list(plot2, 1, 2),
list(plot3, 2, 1),
list(plot4, 2, 2),
list(plot5, 3, 1:2),
list(plot6, 4, 1:2),
list(plot7, 1:2, 3))
lay_out = function(...) {
x <- list(...)
n <- max(sapply(x, function(x) max(x[[2]])))
p <- max(sapply(x, function(x) max(x[[3]])))
grid::pushViewport(grid::viewport(layout = grid::grid.layout(n, p)))
for (i in seq_len(length(x))) {
print(x[[i]][[1]], vp = grid::viewport(layout.pos.row = x[[i]][[2]],
layout.pos.col = x[[i]][[3]]))
}
}
(コードは以前のバージョンからソースされています。 wq
パッケージから、 非公式 Github CRAN ミラー上のコミット履歴.)
に関する答えは、 grid.layout
機能します、私はそれを使用しました、そして私はそれに賛成票を投じました。しかし、私は通常、この解決策は非常に退屈でエラーが発生しやすいと感じています。また、これを定期的に実行しているほとんどの ggplot2 愛好家は、これを関数にまとめているのではないかと思います。以前の検索でそのようなラッピング関数をいくつか見つけましたが、現在の主力ソリューションは グリッド アドオン パッケージと呼ばれる gridExtra
. 。便利な引数がありますが、多くの場合、デフォルトの行/列設定が最初に必要なものになります。
library("ggplot2")
# Generate list of arbitrary ggplots
plot1 <- qplot(data = mtcars, x=wt, y=mpg, geom="point",main="Scatterplot of wt vs. mpg")
plot2 <- qplot(data = mtcars, x=wt, y=disp, geom="point",main="Scatterplot of wt vs disp")
plot3 <- qplot(wt,data=mtcars)
plot4 <- qplot(wt,mpg,data=mtcars,geom="boxplot")
plot5 <- qplot(wt,data=mtcars)
plot6 <- qplot(mpg,data=mtcars)
plot7 <- qplot(disp,data=mtcars)
# You might have produced myPlotList using instead lapply, mc.lapply, plyr::dlply, etc
myPlotList = list(plot1, plot2, plot3, plot4, plot5, plot6, plot7)
library("gridExtra")
do.call(grid.arrange, myPlotList)
実際の「プロットを 1 つのグラフィックに結合する」コードが 1 行であることに注目してください (gridExtra のロード後)。プロットをリストに入れるのは余分な行であると主張するかもしれませんが、実際には代わりに次のようにすることもできました。
grid.arrange(plot1, plot2, plot3, plot4, plot5, plot6, plot7)
ggplot の数が少ない場合は、これが望ましいかもしれません。ただし、 n_plots > 4
すべてに名前を付けて入力する必要があることにうんざりし始めるでしょう。