ggplot2
中的分面图的巨大粉丝。但是,有时我会有太多的子图,并且很容易将它们分解成一个图表列表。例如
df <- data.frame(x=seq(1,24,1), y=seq(1,24,1), z=rep(seq(1,12),each=2))
df
x y z
1 1 1 1
2 2 2 1
3 3 3 2
4 4 4 2
5 5 5 3
. . . .
. . . .
myplot <- ggplot(df,aes(x=x, y=y))+geom_point()+facet_wrap(~z)
myplot
我如何编写一个函数来获取结果图并将其拆分成一个图表列表?沿着这些方向的东西
splitFacet <- function(subsPerPlot){
# Method to break a single facet plot into a list of facet plots, each with at most `subsPerPlot` subplots
# code...
return(listOfPlots)
}
答案 0 :(得分:11)
我们按照以下步骤构建一个函数:
'z'
)。facet
对象中的元素覆盖绘图对象的ggplot
元素(因此,如果我们在此阶段进行打印,则刻面消失了)。12
次),并将所有输出存储在列表中。代码
splitFacet <- function(x){
facet_vars <- names(x$facet$params$facets) # 1
x$facet <- ggplot2::ggplot()$facet # 2
datasets <- split(x$data, x$data[facet_vars]) # 3
new_plots <- lapply(datasets,function(new_data) { # 4
x$data <- new_data
x})
}
new_plots <- splitFacet(myplot)
length(new_plots) # [1] 12
new_plots[[3]] # 3rd plot
n
个子图的多面图如果我们要保留构面但按构面划分的图较少,则可以跳过第2步,而是重新分割拆分,以便它包含用于构面的变量的多个值。
n
是通过绘制获得的构面数量,而不是单独构建函数,我们将概括第一个。
n = NULL
表示您得到的是先前的输出,它与n = 1
略有不同(按图一个面)。
splitFacet <- function(x, n = NULL){
facet_vars <- names(x$facet$params$facets) # 1
if(is.null(n)){
x$facet <- ggplot2::ggplot()$facet # 2a
datasets <- split(x$data, x$data[facet_vars]) # 3a
} else {
inter0 <- interaction(x$data[facet_vars], drop = TRUE) # 2b
inter <- ceiling(as.numeric(inter0)/n)
datasets <- split(x$data, inter) # 3b
}
new_plots <- lapply(datasets,function(new_data) { # 4
x$data <- new_data
x})
}
new_plots2 <- splitFacet(myplot,4)
length(new_plots2) # [1] 3
new_plots2[[2]]
这也可能派上用场:
unfacet <- function(x){
x$facet <- ggplot2::ggplot()$facet
x
}
如果代码可用,则无需经历所有麻烦,我们可以先拆分数据,然后再将数据提供给ggplot
:
library(tidyverse)
myplots3 <-
df %>%
split(ceiling(group_indices(.,z)/n_facets)) %>%
map(~ggplot(.,aes(x =x, y=y))+geom_point()+facet_wrap(~z))
myplots3[[3]]
答案 1 :(得分:5)
虽然我正在为此寻找解决方案,但我可以跨越ggplus。特别是函数facet_multiple
:
https://github.com/guiastrennec/ggplus
它允许您通过指定每页所需的绘图量来分割多个页面上的构面。在您的示例中,它将是:
library(ggplus)
df <- data.frame(x=seq(1,24,1), y=seq(1,24,1), z=rep(seq(1,12),each=2))
myplot <- ggplot(df,aes(x=x, y=y))+geom_point()
facet_multiple(plot = myplot, facets = 'z', ncol = 2, nrow = 2)
这是你需要的吗?它对我有用。
答案 2 :(得分:2)
这类似于Moody_Muddskipper的回答,但可用于任何类型的构面(facet_grid
或facet_wrap
),可处理构面中的任意表达式,并且不会绘制构面条。
library(rlang)
library(ggplot2)
split_facets <- function(x) {
facet_expr <- unlist(x[["facet"]][["params"]][c("cols", "rows", "facets")])
facet_levels <- lapply(facet_expr, rlang::eval_tidy, data = x[["data"]])
facet_id <- do.call(interaction, facet_levels)
panel_data <- split(x[["data"]], facet_id)
plots <- vector("list", length(panel_data))
for (ii in seq_along(plots)) {
plots[[ii]] <- x
plots[[ii]][["data"]] <- panel_data[[ii]]
plots[[ii]][["facet"]] <- facet_null()
}
plots
}
split_facets(ggplot(df,aes(x=x, y=y))+geom_point()+facet_wrap(~z))
split_facets(ggplot(df,aes(x=x, y=y))+geom_point()+facet_grid(z %% 2 ~ z %% 5))
它使用rlang::eval_tidy
来评估构面表达式,将它们组合成一个单一的分类因子,然后使用它来拆分数据。通过用facet_null()
替换每个子图的刻面部分,它也“抑制”了它。
答案 3 :(得分:0)
将其发布给想要使用ggplus的任何人。 ggplus可以在R的更高版本中使用,但是您需要按照开发人员的指导进行安装,即
devtools::install_github("guiastrennec/ggplus")
当我尝试使用RStudio安装它时遇到了相同的问题,然后意识到它不是“标准软件包”之一。我正在使用3.4.4。