网格上的 ggplot 和 R 中的 grobList
ggplot on grid with a grobList in R
我正在尝试在 for 循环中使用 ggplot2 在网格上绘制多个图,然后是 grid.arrange
。但是之后所有的情节都是相同的。
library(ggplot2)
library(grid)
test = data.frame(matrix(rnorm(320), ncol=16 ))
names(test) = sapply(1:16, function(x) paste0("var_",as.character(x)))
plotlist = list()
for (i in 1:(dim(test)[2]-1)){
plotlist[[i]] = ggplot(test) +
geom_point(aes(get(x=names(test)[dim(test)[2]]), y=get(names(test)[i])))
}
pdf("output.pdf")
do.call(grid.arrange, list(grobs=plotlist, nrow=3))
dev.off(4)
当 运行 这段代码时,似乎 get()
调用仅在 grid.arrange
调用时进行评估,因此图中的所有 y 向量都是相同的作为 "var_15"。有没有办法强制立即进行评估,以便我得到 15 个不同的地块?
谢谢!
试试这个:
library(ggplot2)
library(grid)
library(gridExtra)
set.seed(1234)
test = data.frame(matrix(rnorm(320), ncol=16 ))
names(test) = sapply(1:16, function(x) paste0("var_",as.character(x)))
plotlist = list()
for (i in 1:(dim(test)[2]-1)) {
# Define here the dataset for the i-th plot
df <- data.frame(x=test$var_16, y=test[, i])
plotlist[[i]] = ggplot(data=df, aes(x=x, y=y)) + geom_point()
}
grid.arrange(grobs=plotlist, nrow=3)
这里有两种使用 purrr::map
函数而不是 for 循环的方法。我发现当我尝试使用循环时,我对正在发生的事情不太清楚,而且由于 apply
和 map
系列等函数非常适合 R 的向量运算范式,我通常改用映射。
第一个例子使用了cowplot::plot_grid
,它可以得到一个地块列表并排列它们。第二个使用较新的 patchwork
包,它允许您将绘图一起添加——就像字面上说 plot1 + plot2
——并添加布局。为了完成所有这些添加,我使用 purrr::reduce
和 +
作为应用于所有绘图的函数。
library(tidyverse)
set.seed(722)
test = data.frame(matrix(rnorm(320), ncol=16 ))
names(test) = sapply(1:16, function(x) paste0("var_",as.character(x)))
# extract all but last column
xvars <- test[, -ncol(test)]
通过使用 purrr::imap
,我可以映射所有列并应用具有 2 个参数的函数:列本身及其名称。这样我就可以设置一个指定列名的 x 轴标签。我还可以轻松访问数据列,而无需使用 get
或任何 tidyeval 技巧(尽管对于复杂的事情,tidyeval 解决方案可能更好)。
plots <- imap(xvars, function(variable, var_name) {
df <- data_frame(x = variable, y = test[, ncol(test)])
ggplot(df, aes(x = x, y = y)) +
geom_point() +
xlab(var_name)
})
cowplot::plot_grid(plotlist = plots, nrow = 3)
library(patchwork)
# same as plots[[1]] + plots[[2]] + plots[[3]] + ...
reduce(plots, `+`) + plot_layout(nrow = 3)
由 reprex package (v0.2.0) 创建于 2018-07-22。
我正在尝试在 for 循环中使用 ggplot2 在网格上绘制多个图,然后是 grid.arrange
。但是之后所有的情节都是相同的。
library(ggplot2)
library(grid)
test = data.frame(matrix(rnorm(320), ncol=16 ))
names(test) = sapply(1:16, function(x) paste0("var_",as.character(x)))
plotlist = list()
for (i in 1:(dim(test)[2]-1)){
plotlist[[i]] = ggplot(test) +
geom_point(aes(get(x=names(test)[dim(test)[2]]), y=get(names(test)[i])))
}
pdf("output.pdf")
do.call(grid.arrange, list(grobs=plotlist, nrow=3))
dev.off(4)
当 运行 这段代码时,似乎 get()
调用仅在 grid.arrange
调用时进行评估,因此图中的所有 y 向量都是相同的作为 "var_15"。有没有办法强制立即进行评估,以便我得到 15 个不同的地块?
谢谢!
试试这个:
library(ggplot2)
library(grid)
library(gridExtra)
set.seed(1234)
test = data.frame(matrix(rnorm(320), ncol=16 ))
names(test) = sapply(1:16, function(x) paste0("var_",as.character(x)))
plotlist = list()
for (i in 1:(dim(test)[2]-1)) {
# Define here the dataset for the i-th plot
df <- data.frame(x=test$var_16, y=test[, i])
plotlist[[i]] = ggplot(data=df, aes(x=x, y=y)) + geom_point()
}
grid.arrange(grobs=plotlist, nrow=3)
这里有两种使用 purrr::map
函数而不是 for 循环的方法。我发现当我尝试使用循环时,我对正在发生的事情不太清楚,而且由于 apply
和 map
系列等函数非常适合 R 的向量运算范式,我通常改用映射。
第一个例子使用了cowplot::plot_grid
,它可以得到一个地块列表并排列它们。第二个使用较新的 patchwork
包,它允许您将绘图一起添加——就像字面上说 plot1 + plot2
——并添加布局。为了完成所有这些添加,我使用 purrr::reduce
和 +
作为应用于所有绘图的函数。
library(tidyverse)
set.seed(722)
test = data.frame(matrix(rnorm(320), ncol=16 ))
names(test) = sapply(1:16, function(x) paste0("var_",as.character(x)))
# extract all but last column
xvars <- test[, -ncol(test)]
通过使用 purrr::imap
,我可以映射所有列并应用具有 2 个参数的函数:列本身及其名称。这样我就可以设置一个指定列名的 x 轴标签。我还可以轻松访问数据列,而无需使用 get
或任何 tidyeval 技巧(尽管对于复杂的事情,tidyeval 解决方案可能更好)。
plots <- imap(xvars, function(variable, var_name) {
df <- data_frame(x = variable, y = test[, ncol(test)])
ggplot(df, aes(x = x, y = y)) +
geom_point() +
xlab(var_name)
})
cowplot::plot_grid(plotlist = plots, nrow = 3)
library(patchwork)
# same as plots[[1]] + plots[[2]] + plots[[3]] + ...
reduce(plots, `+`) + plot_layout(nrow = 3)
由 reprex package (v0.2.0) 创建于 2018-07-22。