如何绘制带填充分组的百分比分面直方图?
问题描述
我想要绘制一个带有分面和填充分组变量的百分比直方图。此前相关讨论未涉及填充分组变量,使用density的解决方案结果异常:代码中第一条geom_histogram语句生成的R分组线条不正确,第二条则生成正常计数。如何输出正确的分面百分比?
附带代码:
values <- sample(c(4,8,16,32,64,128,256,512),1000,replace=TRUE) groups <- sample(c("A","B","C","D"),1000,replace=TRUE) daf <- data.frame(group=groups,value=values) daf$state <- "S" daf$state[daf$group == "A" & daf$value > 16] <- "R" daf$state[daf$group == "B" & daf$value > 64] <- "R" daf$state[daf$group == "C" & daf$value > 32] <- "R" daf$state[daf$group == "D" & daf$value > 256] <- "R" p <- ggplot(daf, aes(x=value,fill=state)) + geom_histogram(aes(y = stat(density)*0.5),binwidth=0.5) + # geom_histogram(aes(y = stat(count)),binwidth=0.5) + scale_x_continuous(name = "log2-trans",trans="log2",labels = scales::math_format(2^.x, format = log2),breaks = c(0.015625,0.03125,0.0625,0.125,0.25,0.5,0,1,2,4,8,16,32,64,128,256,512)) + scale_y_continuous(name = "Count")+ facet_wrap(~ group,nrow=5,ncol=3,scales = "free")+ theme_minimal()+ theme(legend.position = "bottom") p
解决方案
核心问题是stat(density)不适合用于对数变换轴下的百分比计算——密度是连续分布的估计值,和实际计数的占比逻辑不符,且未按分面做归一化。正确做法是基于计数直接计算分面内的百分比:
修改后的代码如下:
library(ggplot2) library(scales) values <- sample(c(4,8,16,32,64,128,256,512),1000,replace=TRUE) groups <- sample(c("A","B","C","D"),1000,replace=TRUE) daf <- data.frame(group=groups,value=values) daf$state <- "S" daf$state[daf$group == "A" & daf$value > 16] <- "R" daf$state[daf$group == "B" & daf$value > 64] <- "R" daf$state[daf$group == "C" & daf$value > 32] <- "R" daf$state[daf$group == "D" & daf$value > 256] <- "R" p <- ggplot(daf, aes(x=value, fill=state)) + # 按分面计算百分比:当前区间计数 / 分面总计数 * 100 geom_histogram(aes(y = after_stat(count) / sum(after_stat(count)) * 100), binwidth=0.5, position="stack") + scale_x_continuous(name = "log2-转换值", trans="log2", labels = math_format(2^.x, format = log2), breaks = c(0.015625,0.03125,0.0625,0.125,0.25,0.5,0,1,2,4,8,16,32,64,128,256,512)) + scale_y_continuous(name = "百分比(%)", labels = percent_format(scale = 1)) + facet_wrap(~ group, nrow=5, ncol=3, scales = "free") + theme_minimal() + theme(legend.position = "bottom") p
关键说明
after_stat(count)是ggplot2 3.3.0及以上版本的推荐用法,用于获取直方图计算后的区间计数sum(after_stat(count))会自动按分面(group)计算总计数,保证百分比是相对于当前分面的整体数据- 若需要每个区间内的state占比为100%(即每个柱子高度统一为100%),可将
position="fill",同时y轴表达式改为after_stat(count)/sum(after_stat(count)),配合labels = percent_format()即可
内容的提问来源于stack exchange,提问作者Peter Pisher
相关产品推荐
相关产品推荐

