我有一个data.frame
,我想用ggplot2
的geom_bar
生成条形图,由data.frame
-cluster
中的一列分面:
library(dplyr)
df <- data.frame(cluster = c("c1","c1","c1","c2","c2","c2","c3","c3","c3"), group = rep(c("A","B","C"),3), p = c(0.4,0.2,0.4,0.5,0.5,0.5,0.2,0.3,0.5))
很明显如何用ggplot2
的facet_wrap
:
library(ggplot2)
ggplot(df, aes(x = group, y = p, group = cluster, fill = group)) +
geom_bar(stat = 'identity') +
scale_x_discrete(name = NULL,labels = levels(df$group), breaks = sort(unique(df$group))) +
facet_wrap(as.formula("~ cluster")) + theme_minimal() + theme(legend.title = element_blank()) + ylab("Fraction of cells")
但是由于这篇文章中没有提到的原因(不是很相关),facet_wrap
不适合我,我需要求助于生成一个图表列表,每个集群一个,并将它们自己安排在一个网格中:
plot.list <- lapply(unique(df$cluster),function(l){
ggplot(dplyr::filter(df,cluster == l), aes(x = group, y = p, fill = group)) +
geom_bar(stat = 'identity') +
scale_x_discrete(name = NULL,labels = levels(dplyr::filter(df,cluster == l)$group), breaks = sort(unique(dplyr::filter(df,cluster == l)$group))) +
theme_minimal() + theme(legend.title = element_blank(), plot.title = element_text(hjust = 0.5)) + ylab("Fraction of cells") + ggtitle(l)
})
facet_wrap
有两个好处,我错过了不使用它,我试图找到如何保留:
- 自动决定网格布局的尺寸:是否知道
facet_wrap
是如何做到这一点的,也许如果这些信息可以从使用上面的facet_wrap
命令运行的绘图中提取? facet_wrap
也自动共享轴标题和刻度,但gridExtra::grid.arrange
或scater::multiplot
没有。使用这些函数实现这一点的唯一方法是对lapply
调用中的所有集群抑制这些themes
,用户不希望出现这些标签(模仿facet_wrap
)。我想问题1的答案提供了这个问题的答案(在所需网格中集群位置的条件轴标签抑制),但如果有人有更直接的解决方案,那就太好了。
换句话说,我正在寻找一种通用的方法来重现使用facet_wrap
上面的gridExtra::grid.arrange
或scater::multiplot
(或任何其他功能)应用于plot.list
的情节网格
可以在wrap_dims函数中找到facet_wrap绘图的尺寸。
x=ggplot(df, aes(x = group, y = p, group = cluster, fill = group)) +
geom_bar(stat = 'identity') +
scale_x_discrete(name = NULL,labels = levels(df$group), breaks = sort(unique(df$group))) +
facet_wrap(as.formula("~ cluster")) + theme_minimal() + theme(legend.title = element_blank()) + ylab("Fraction of cells")
col=wrap_dims(length(x))[2]
plot.list=list()
for (i in 1:length(unique(df$cluster))) {
y=ggplot(dplyr::filter(df,cluster == unique(df$cluster)[i]), aes(x = group, y = p, fill = group)) +
geom_bar(stat = 'identity') +
scale_x_discrete(name = NULL,labels = levels(dplyr::filter(df,cluster == unique(df$cluster)[i])$group), breaks = sort(unique(dplyr::filter(df,cluster == unique(df$cluster)[i])$group))) +
theme_minimal() + theme(plot.title = element_text(hjust = 0.5)) + ggtitle(unique(df$cluster)) + ylim(0, max(df$p))
if (i<length(unique(df$cluster))) {
y=y+theme(legend.position="none")
}
if (i>1) {
y=y+ylab("")
} else {
y=y+ylab("Fraction of cells")
}
plot.list[[i]]=y
}
do.call(grid.arrange, c(plot.list, ncol=col))