如何在一个窗口上指定并排打印的数量 让我们考虑以下四个图: library(ggplot2) library(cowplot) set.seed(42) vec_1 <- rnorm(100) vec_2 <- runif(100) vec_3 <- rexp(100) vec_4 <- rpois(100,1) plot_1 <- ggplot()+aes(x=1:length(vec_1), y= vec_1) + geom_line() + xlab(NULL) + ylab('Norm') plot_2 <- ggplot()+aes(x=1:length(vec_2), y= vec_2) + geom_line() + xlab(NULL) + ylab('Unif') plot_3 <- ggplot()+aes(x=1:length(vec_3), y= vec_3) + geom_line() + xlab(NULL) + ylab('Exp') plot_4 <- ggplot()+aes(x=1:length(vec_4), y= vec_4) + geom_line() + xlab(NULL) + ylab('Poiss') plot_grids(plot_1, plot_2, plot_3, plot_4, plot_4, plot_4, ncol = 3L, nrow = 2L)
这是很容易做到的,但是-有没有可能一个命令就可以做到呢?例如,我试过如何在一个窗口上指定并排打印的数量 让我们考虑以下四个图: library(ggplot2) library(cowplot) set.seed(42) vec_1 <- rnorm(100) vec_2 <- runif(100) vec_3 <- rexp(100) vec_4 <- rpois(100,1) plot_1 <- ggplot()+aes(x=1:length(vec_1), y= vec_1) + geom_line() + xlab(NULL) + ylab('Norm') plot_2 <- ggplot()+aes(x=1:length(vec_2), y= vec_2) + geom_line() + xlab(NULL) + ylab('Unif') plot_3 <- ggplot()+aes(x=1:length(vec_3), y= vec_3) + geom_line() + xlab(NULL) + ylab('Exp') plot_4 <- ggplot()+aes(x=1:length(vec_4), y= vec_4) + geom_line() + xlab(NULL) + ylab('Poiss') plot_grids(plot_1, plot_2, plot_3, plot_4, plot_4, plot_4, ncol = 3L, nrow = 2L),r,ggplot2,split,R,Ggplot2,Split,这是很容易做到的,但是-有没有可能一个命令就可以做到呢?例如,我试过 plot_grid(plot_1, plot_2, plot_3, plot_4, ncol = 2, nrow = 1), 但它只是截断了剩余的图。换句话说,我正在寻找一个解决方案,在这个解决方案中,我可以提供所有四个图,它将它们分成两个并排的图,其中包含两个图。我想要这样的解决方案,因为它可以简化我正在编写的复杂函数中的很多事情 关于facet_grid()函数 我试图使用它,但是如果我想得到与上面相同的结果(即,两个并
plot_grid(plot_1, plot_2, plot_3, plot_4, ncol = 2, nrow = 1),
但它只是截断了剩余的图。换句话说,我正在寻找一个解决方案,在这个解决方案中,我可以提供所有四个图,它将它们分成两个并排的图,其中包含两个图。我想要这样的解决方案,因为它可以简化我正在编写的复杂函数中的很多事情
关于facet_grid()函数
我试图使用它,但是如果我想得到与上面相同的结果(即,两个并排的两个图形的两倍),我使用:
我想获得两个图形,其中包含一行两列并排的绘图(就像我用plot\u grid()
展示的那样),但是我得到了错误:error:给定的尺寸不能容纳所有面板。请增加
ncol或
nrow
编辑
我尝试对以下数据运行函数plot_grids():
library(ggplot2)
library(cowplot)
set.seed(42)
vec_1 <- rnorm(100)
vec_2 <- runif(100)
vec_3 <- rexp(100)
vec_4 <- rpois(100,1)
plot_1 <- ggplot()+aes(x=1:length(vec_1), y= vec_1) + geom_line() + xlab(NULL) + ylab('Norm')
plot_2 <- ggplot()+aes(x=1:length(vec_2), y= vec_2) + geom_line() + xlab(NULL) + ylab('Unif')
plot_3 <- ggplot()+aes(x=1:length(vec_3), y= vec_3) + geom_line() + xlab(NULL) + ylab('Exp')
plot_4 <- ggplot()+aes(x=1:length(vec_4), y= vec_4) + geom_line() + xlab(NULL) + ylab('Poiss')
plot_grids(plot_1, plot_2, plot_3, plot_4, plot_4, plot_4, ncol = 3L, nrow = 2L)
但我得到这些警告:
45: In as_grob.default(plot) : Cannot convert object of class list into a grob.
46: In as_grob.default(plot) : Cannot convert object of class waiver into a grob.
47: In as_grob.default(plot) : Cannot convert object of class list into a grob.
48: In as_grob.default(plot) :
Cannot convert object of class ScalesListggprotogg into a grob.
49: In as_grob.default(plot) : Cannot convert object of class uneval into a grob.
50: In as_grob.default(plot) : Cannot convert object of class list into a grob.
编辑
现在我试图调整代码,使其与不正确的维数兼容,例如,如果我们有6个图要绘制,并且我们指定ncol=2和nrow=2,我想得到两个并排的图。第一个我想要四个图,第二个我想要剩下的两个。如果需要,我尝试添加空绘图:
plot_grids = function (plotlist = NULL, nrow, ncol) {
plots_per_fig = nrow * ncol
if (length(plotlist) %% plots_per_fig !=0) {
df <- data.frame()
for (i in 1:(length(plotlist) %% plots_per_fig)) {
plotlist[[(length(plotlist)+i)]] <- ggplot(df)
}
}
num_figs = length(plotlist) / plots_per_fig
groups = if (num_figs == 1) list(plotlist)
else unname(split(plotlist, cut(seq_along(plotlist), num_figs)))
plot_grid_wrapper = function (plotlist) {
do.call(
cowplot::plot_grid,
c(list(plotlist = plotlist, nrow = nrow, ncol = ncol))
)
}
lapply(groups, plot_grid_wrapper)
}
仅给出部分正确的结果:
第一张图片:
第二幅图像:
如果第二张图片上有两个非空图形,而不是一个,一切都会很好。你知道为什么会这样吗
vecs = list(vec_1, vec_2, vec_3, vec_4)
data = data.frame(
x = unlist(lapply(lengths(vecs), seq)),
y = unlist(vecs),
dist = rep(c('normal', 'uniform', 'exponential', 'poisson'), times = lengths(vecs))
)
ggplot(data) +
aes(x = x, y = y) +
geom_line() +
facet_wrap(~ dist, ncol = 2L)
ggplot2
之前对其进行过滤(我使用'dplyr'中的filter
,但任何方法都可以):
要在侧面而不是顶部获得单独的y轴和标签,可以修改facet\u wrap
调用,如下所示:
facet_wrap(~ dist, ncol = 2L, strip.position = 'left', scales = 'free') +
ylab('')
要更改镶嵌条标签的外观,可以。要获得与屏幕截图几乎相同的外观,请使用
theme(
strip.background = element_rect(fill = 'white'),
strip.placement = 'outside'
)
vecs = list(vec_1, vec_2, vec_3, vec_4)
data = data.frame(
x = unlist(lapply(lengths(vecs), seq)),
y = unlist(vecs),
dist = rep(c('normal', 'uniform', 'exponential', 'poisson'), times = lengths(vecs))
)
ggplot(data) +
aes(x = x, y = y) +
geom_line() +
facet_wrap(~ dist, ncol = 2L)
ggplot2
之前对其进行过滤(我使用'dplyr'中的filter
,但任何方法都可以):
要在侧面而不是顶部获得单独的y轴和标签,可以修改facet\u wrap
调用,如下所示:
facet_wrap(~ dist, ncol = 2L, strip.position = 'left', scales = 'free') +
ylab('')
要更改镶嵌条标签的外观,可以。要获得与屏幕截图几乎相同的外观,请使用
theme(
strip.background = element_rect(fill = 'white'),
strip.placement = 'outside'
)
plot\u grid
始终生成单个绘图。您可以将其包装为一个简单的函数,以扩展它以生成多个绘图:
#' Arrange plots into multiple grids
#'
#' \code{plot_grids} extends \code{\link[cowplot]{plot_grid}} by generating a list
#' of multiple grids of plots.
#'
#' @param ... list of plots
#' @param plotlist optional plots as a list
#' @param nrow number of rows of plots per grid
#' @param ncol number of colums of plots per grid
#' @param plot_grid_args named vector of further arguments to pass to
#' \code{\link[cowplot]{plot_grid}}
#' @return \code{plot_grids} returns a list of plots, each generated by
#' \code{\link[cowplot]{plot_grid}} with a subset of the plots passed via
#' \code{...} or \code{plotlist}.
plot_grids = function (..., plotlist = NULL, nrow, ncol, plot_grid_args = NULL) {
plots = c(list(...), plotlist)
plots_per_fig = nrow * ncol
num_figs = length(plots) / plots_per_fig
groups = if (num_figs == 1L) list(plots)
else unname(split(plots, cut(seq_along(plots), num_figs)))
plot_grid_wrapper = function (plotlist) {
do.call(
cowplot::plot_grid,
c(list(plotlist = plotlist, nrow = nrow, ncol = ncol), plot_grid_args)
)
}
lapply(groups, plot_grid_wrapper)
}
然后呢,
figs = plot_grids(plot_1, plot_2, plot_3, plot_4, ncol = 2L, nrow = 1L)
plot\u grid
始终生成单个绘图。您可以将其包装为一个简单的函数,以扩展它以生成多个绘图:
#' Arrange plots into multiple grids
#'
#' \code{plot_grids} extends \code{\link[cowplot]{plot_grid}} by generating a list
#' of multiple grids of plots.
#'
#' @param ... list of plots
#' @param plotlist optional plots as a list
#' @param nrow number of rows of plots per grid
#' @param ncol number of colums of plots per grid
#' @param plot_grid_args named vector of further arguments to pass to
#' \code{\link[cowplot]{plot_grid}}
#' @return \code{plot_grids} returns a list of plots, each generated by
#' \code{\link[cowplot]{plot_grid}} with a subset of the plots passed via
#' \code{...} or \code{plotlist}.
plot_grids = function (..., plotlist = NULL, nrow, ncol, plot_grid_args = NULL) {
plots = c(list(...), plotlist)
plots_per_fig = nrow * ncol
num_figs = length(plots) / plots_per_fig
groups = if (num_figs == 1L) list(plots)
else unname(split(plots, cut(seq_along(plots), num_figs)))
plot_grid_wrapper = function (plotlist) {
do.call(
cowplot::plot_grid,
c(list(plotlist = plotlist, nrow = nrow, ncol = ncol), plot_grid_args)
)
}
lapply(groups, plot_grid_wrapper)
}
然后呢,
figs = plot_grids(plot_1, plot_2, plot_3, plot_4, ncol = 2L, nrow = 1L)
谢谢你的回答,康拉德,但是你的代码将所有四个图都绘制在一起,这并不是我想要的。有关更多详细信息,请查看我更新的问题。@John我真的不明白问题所在:我的代码生成的排列与您的屏幕截图中的完全相同。唯一的区别是绘图的顺序,可以通过将
dist
设置为有序因子来指定。不完全相同-您有一个绘图包含四个绘图,我有两个绘图包含两个绘图;)@约翰:好的,从截图上看不到但是好的,这很容易实现,只需在将数据传递到ggplot
之前过滤数据。请参阅更新的答案。是的,您是对的,我更改了一点屏幕截图的外观以使其更可见;))在将数据传递给ggplot之前,您能告诉我过滤数据的确切含义吗?我不知道这对我的问题有什么帮助。谢谢你的回答,康拉德,但是你的代码将所有四个图都绘制在一起,这并不是我想要的。有关更多详细信息,请查看我更新的问题。@John我真的不明白问题所在:我的代码生成的排列与您的屏幕截图中的完全相同。唯一的区别是绘图的顺序,可以通过将dist
设置为有序因子来指定。不完全相同-您有一个绘图包含四个绘图,我有两个绘图包含两个绘图;)@约翰:好的,从截图上看不到但是好的,这很容易实现,只需在将数据传递到ggplot
之前过滤数据。请参阅更新的答案。是的,您是对的,我更改了一点屏幕截图的外观以使其更可见;))在将数据传递给ggplot之前,您能告诉我过滤数据的确切含义吗?我不确定它对我的问题有什么帮助。这个函数基本上已经存在于patchwork::wrap_plots中,它以ggplot对象为对象list@tjebowrap_plots
是否生成绘图列表?据我所知,它总是生成单个绘图,示例为plot\u grid
。这就是说,对“拼凑”的呼喊是好的:我相信它本质上取代了“cowplot”来安排情节。但我并没有真正使用这两种方法,所以我不是专家。你是对的,对不起,我认为我误解了OP,然后也误读了你的函数:)我个人更喜欢拼凑,但cowplot有它的优点。这是一个相当好的代码,但为什么如果我有ncol=2,nrow=2,我会看到错误无效的间隔数?我想它应该把所有的东西都画在一个图上,对吗?@John是的,我没有解释那个案例,因为这样你就可以调用plot\u grid
,对吗?现在已修复。该函数基本上已存在