R中geom_histogram设置position="identity"时相同数据集显示不一致如何解决
问题成因
你遇到的红色直方图表现不一致,核心原因是geom_histogram()在仅指定bins=30参数时,会自动根据当前传入的整个绘图数据集的取值范围计算bin的边界、宽度。你每张子图的输入数据集是固定的红色1000样本+不同数量的蓝色子样本,不同子图的整体取值范围存在差异,导致bin的划分规则不统一:哪怕红色样本完全相同,相同取值会被划入不同的bin,最终计数、分布展示出现差异,子样本量越小,整体取值范围波动越大,差异越明显,符合你观察到的250样本子图差异最显著的现象。
解决方案
- 方案1:统一指定所有直方图的bin边界
提前计算所有样本的取值上下限,生成固定的bin断点,所有子图绘图时都传入该断点,替换原有bins=30参数即可。示例代码如下:
# 提取所有样本的取值,计算统一断点 all_val <- c(test$value, test_2$value, test_3$value, test_4$value, test_5$value, test_6$value) # 30个bin对应31个断点 uni_breaks <- seq(min(all_val), max(all_val), length.out = 31) # 绘图时替换参数,以其中一个图为例,其余图做相同修改即可 draws_750_p<-ggplot(data = test_2_final, aes(x=value, fill=type, color=type)) + geom_histogram(position="identity", alpha = 0.2, breaks = uni_breaks) + theme(plot.title = element_text(hjust = 0.5, size=10, face="plain"))
- 方案2:使用ggplot分面功能替代手动拼接子图
不需要单独生成5张图再用plot_grid拼接,直接把所有数据合并为一张大表,用facet_wrap生成分面,ggplot会自动统一所有分面的bin划分、坐标轴范围,天然保证红色直方图表现一致,同时大幅简化代码:
library(data.table) library(ggplot2) # 生成基础红色样本 base_dt <- data.table(value = rnorm(1000), type = "Sample") # 生成不同大小的蓝色子样本,合并为总表 sub_list <- list( `750` = data.table(value = rnorm(750), type = "Sub Sample"), `500` = data.table(value = rnorm(500), type = "Sub Sample"), `250` = data.table(value = rnorm(250), type = "Sub Sample"), `100` = data.table(value = rnorm(100), type = "Sub Sample"), `50` = data.table(value = rnorm(50), type = "Sub Sample") ) full_dt <- rbindlist(lapply(names(sub_list), function(size) { rbind(base_dt, sub_list[[size]])[, sub_size := size] })) # 直接绘图分面 ggplot(full_dt, aes(x=value, fill=type, color=type)) + geom_histogram(position="identity", alpha = 0.2, bins=30) + facet_wrap(~sub_size, nrow = 2, ncol = 3) + theme(plot.title = element_text(hjust = 0.5, size=10, face="plain"))
内容的提问来源于stack exchange,提问作者bziggy
相关产品推荐
相关产品推荐

