ggplot 中多种因素的颜色和分面
Color and faceting by multiple factors in ggplot
我有一个 data.frame
,我试图以 facetted
的方式与 R
的 ggplot
的 geom_boxplot
一起绘制:
set.seed(1)
vals <- rnorm(12)
min.vals <- vals-0.5
low.vals <- vals-0.25
max.vals <- vals+0.5
high.vals <- vals+0.25
df <- data.frame(sample=c("c0.A_1","c0.A_2","c1.A_1","c1.A_2","c2.A_1","c2.A_2","c0.B_1","c0.B_2","c1.B_1","c1.B_2","c2.B_1","c2.B_2"),
replicate=rep(c(1,2),6),val=vals,min.val=min.vals,low.val=low.vals,max.val=max.vals,high.val=high.vals,
group=c(rep("A",6),rep("B",6)),cycle=rep(c("c0","c0","c1","c1","c2","c2"),2),
stringsAsFactors = F)
在这个例子中有两个因素我想要 facet
:
facet.factors <- c("group","cycle")
for(f in 1:length(facet.factors)) df[,facet.factors[f]] <- factor(df[,facet.factors[f]],levels=unique(df[,facet.factors[f]]))
levels.vec <- sapply(facet.factors,function(f) length(levels(df[,f])))
但在其他情况下我可能只有一个或两个以上的因素。
有没有办法向 facet_wrap
传递分面的因子向量和列数?
这是我尝试过的方法,此外我还为每个因子级别创建了自己的颜色:
library(RColorBrewer,quietly=T)
library(scales,quietly=T)
level.colors <- brewer.pal(sum(levels.vec),"Set2")
require(ggplot2)
ggplot(df,aes_string(x="replicate",ymin="min.val",lower="low.val",middle="val",upper="high.val",ymax="max.val",col=facet.factors,fill=facet.factors))+
geom_boxplot(position=position_dodge(width=0),alpha=0.5,stat="identity")+
facet_wrap(~facet.factors,ncol=max(levels.vec))+
labs(x="Replicate",y="Val")+
scale_x_continuous(breaks=unique(df$replicate))+
scale_color_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+scale_fill_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+
theme_bw()+theme(legend.position="none",panel.border=element_blank(),strip.background=element_blank(),axis.title=element_text(size=8))
这显然会引发此错误:
Error in combine_vars(data, params$plot_env, vars, drop = params$drop) :
At least one layer must contain all variables used for facetting
显然这有效:
ggplot(df,aes_string(x="replicate",ymin="min.val",lower="low.val",middle="val",upper="high.val",ymax="max.val",col=facet.factors,fill=facet.factors))+
geom_boxplot(position=position_dodge(width=0),alpha=0.5,stat="identity")+
facet_wrap(group~cycle,ncol=max(levels.vec))+
labs(x="Replicate",y="Val")+
scale_x_continuous(breaks=unique(df$replicate))+
scale_color_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+scale_fill_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+
theme_bw()+theme(legend.position="none",panel.border=element_blank(),strip.background=element_blank(),axis.title=element_text(size=8))
但它忽略了我传递的颜色并且不添加图例,我想因为我无法将 vector
传递给 col
和 fill
in [=26] =],显然我必须对分面进行硬编码。
这对分面问题也不起作用:
ggplot(df,aes_string(x="replicate",ymin="min.val",lower="low.val",middle="val",upper="high.val",ymax="max.val",col=facet.factors,fill=facet.factors))+
geom_boxplot(position=position_dodge(width=0),alpha=0.5,stat="identity")+
facet_wrap(facet.factors[1]~facet.factors[2],ncol=max(levels.vec))+
labs(x="Replicate",y="Val")+
scale_x_continuous(breaks=unique(df$replicate))+
scale_color_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+scale_fill_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+
theme_bw()+theme(legend.position="none",panel.border=element_blank(),strip.background=element_blank(),axis.title=element_text(size=8))
所以我的问题是:
1.有没有办法将向量传递给facet_wrap?
2. 有没有办法用因子向量而不是单个因子来着色和填充?
我们不能为单个框指定 coloring/filling 的两种颜色,我建议将分面变量粘贴在一起作为 coloring/filling 比例:
df$col.fill <- Reduce(paste, df[facet.factors])
facets
of facet_wrap
接受字符向量或单边公式:
facet.formula <- as.formula(paste('~', paste(facet.factors, collapse = '+')))
所以代码最终看起来像这样:
ggplot(df,
aes_string(
x = "replicate", ymin = "min.val", ymax = "max.val",
lower = "low.val", middle = "val", upper = "high.val",
col = "col.fill", fill = "col.fill"
)) +
geom_boxplot(position = position_dodge(width = 0),
alpha = 0.5,
stat = "identity") +
facet_wrap(facet.factors, ncol = max(levels.vec)) +
# alternatively: facet_wrap(facet.formula, ncol = max(levels.vec)) +
labs(x = "Replicate", y = "Val") +
scale_x_continuous(breaks = unique(df$replicate)) +
theme_bw() +
theme(
#legend.position = "none",
panel.border = element_blank(),
strip.background = element_blank(),
axis.title = element_text(size = 8)
)
图例未显示,因为您添加了 legend.position = "none",
。
顺便说一句,如果您在代码中添加一些 space 和换行符,肯定会提高可读性。
我有一个 data.frame
,我试图以 facetted
的方式与 R
的 ggplot
的 geom_boxplot
一起绘制:
set.seed(1)
vals <- rnorm(12)
min.vals <- vals-0.5
low.vals <- vals-0.25
max.vals <- vals+0.5
high.vals <- vals+0.25
df <- data.frame(sample=c("c0.A_1","c0.A_2","c1.A_1","c1.A_2","c2.A_1","c2.A_2","c0.B_1","c0.B_2","c1.B_1","c1.B_2","c2.B_1","c2.B_2"),
replicate=rep(c(1,2),6),val=vals,min.val=min.vals,low.val=low.vals,max.val=max.vals,high.val=high.vals,
group=c(rep("A",6),rep("B",6)),cycle=rep(c("c0","c0","c1","c1","c2","c2"),2),
stringsAsFactors = F)
在这个例子中有两个因素我想要 facet
:
facet.factors <- c("group","cycle")
for(f in 1:length(facet.factors)) df[,facet.factors[f]] <- factor(df[,facet.factors[f]],levels=unique(df[,facet.factors[f]]))
levels.vec <- sapply(facet.factors,function(f) length(levels(df[,f])))
但在其他情况下我可能只有一个或两个以上的因素。
有没有办法向 facet_wrap
传递分面的因子向量和列数?
这是我尝试过的方法,此外我还为每个因子级别创建了自己的颜色:
library(RColorBrewer,quietly=T)
library(scales,quietly=T)
level.colors <- brewer.pal(sum(levels.vec),"Set2")
require(ggplot2)
ggplot(df,aes_string(x="replicate",ymin="min.val",lower="low.val",middle="val",upper="high.val",ymax="max.val",col=facet.factors,fill=facet.factors))+
geom_boxplot(position=position_dodge(width=0),alpha=0.5,stat="identity")+
facet_wrap(~facet.factors,ncol=max(levels.vec))+
labs(x="Replicate",y="Val")+
scale_x_continuous(breaks=unique(df$replicate))+
scale_color_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+scale_fill_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+
theme_bw()+theme(legend.position="none",panel.border=element_blank(),strip.background=element_blank(),axis.title=element_text(size=8))
这显然会引发此错误:
Error in combine_vars(data, params$plot_env, vars, drop = params$drop) :
At least one layer must contain all variables used for facetting
显然这有效:
ggplot(df,aes_string(x="replicate",ymin="min.val",lower="low.val",middle="val",upper="high.val",ymax="max.val",col=facet.factors,fill=facet.factors))+
geom_boxplot(position=position_dodge(width=0),alpha=0.5,stat="identity")+
facet_wrap(group~cycle,ncol=max(levels.vec))+
labs(x="Replicate",y="Val")+
scale_x_continuous(breaks=unique(df$replicate))+
scale_color_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+scale_fill_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+
theme_bw()+theme(legend.position="none",panel.border=element_blank(),strip.background=element_blank(),axis.title=element_text(size=8))
但它忽略了我传递的颜色并且不添加图例,我想因为我无法将 vector
传递给 col
和 fill
in [=26] =],显然我必须对分面进行硬编码。
这对分面问题也不起作用:
ggplot(df,aes_string(x="replicate",ymin="min.val",lower="low.val",middle="val",upper="high.val",ymax="max.val",col=facet.factors,fill=facet.factors))+
geom_boxplot(position=position_dodge(width=0),alpha=0.5,stat="identity")+
facet_wrap(facet.factors[1]~facet.factors[2],ncol=max(levels.vec))+
labs(x="Replicate",y="Val")+
scale_x_continuous(breaks=unique(df$replicate))+
scale_color_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+scale_fill_manual(values=level.colors,labels=unname(unlist(sapply(facet.factors,function(f) levels(df[,f])))),name="factor level")+
theme_bw()+theme(legend.position="none",panel.border=element_blank(),strip.background=element_blank(),axis.title=element_text(size=8))
所以我的问题是: 1.有没有办法将向量传递给facet_wrap? 2. 有没有办法用因子向量而不是单个因子来着色和填充?
我们不能为单个框指定 coloring/filling 的两种颜色,我建议将分面变量粘贴在一起作为 coloring/filling 比例:
df$col.fill <- Reduce(paste, df[facet.factors])
facets
of facet_wrap
接受字符向量或单边公式:
facet.formula <- as.formula(paste('~', paste(facet.factors, collapse = '+')))
所以代码最终看起来像这样:
ggplot(df,
aes_string(
x = "replicate", ymin = "min.val", ymax = "max.val",
lower = "low.val", middle = "val", upper = "high.val",
col = "col.fill", fill = "col.fill"
)) +
geom_boxplot(position = position_dodge(width = 0),
alpha = 0.5,
stat = "identity") +
facet_wrap(facet.factors, ncol = max(levels.vec)) +
# alternatively: facet_wrap(facet.formula, ncol = max(levels.vec)) +
labs(x = "Replicate", y = "Val") +
scale_x_continuous(breaks = unique(df$replicate)) +
theme_bw() +
theme(
#legend.position = "none",
panel.border = element_blank(),
strip.background = element_blank(),
axis.title = element_text(size = 8)
)
图例未显示,因为您添加了 legend.position = "none",
。
顺便说一句,如果您在代码中添加一些 space 和换行符,肯定会提高可读性。