为何用ggplot2绘制的累积线与直方图百分比显示错误?
问题:ggplot累积占比叠加时百分比显示错误
我用ggplot叠加某列的累积占比时,百分比显示错误。红色累积线起始于95%左右,但第一个直方图柱的累积占比仅约82%。
错误原因
问题出在分箱规则不统一以及超大值对累积计算的影响:
- 数据中存在多个极大值(如125、186、233),
breaks = 0:max(df$col)会生成从0到233的所有整数分箱,大部分数据集中在0-10区间,但有4个值落在10以上的分箱中,占总数据的4%。 - 仅在
geom_histogram中指定了分箱规则,geom_line的stat="bin"使用默认分箱逻辑,导致两者统计的分箱不一致;同时累积计算基于全部分箱的总数据量(100条),0-10区间的总累积占比为96%,这就导致红色线在0-10区间内的起始累积值直接跳到95%左右。
解决方案
方法一:统一分箱规则
在geom_line中指定和geom_histogram相同的breaks参数,确保两者使用同一组分箱统计累积值:
library(ggplot2); library(dplyr) df %>% ggplot(aes(x = col)) + geom_histogram(aes(y = after_stat(cumsum(count / sum(count)))), breaks = 0:max(df$col, na.rm = T), fill = "blue", color = "black") + geom_line(stat = "bin", aes(y = after_stat(cumsum(count / sum(count)))), breaks = 0:max(df$col, na.rm = T), color = "red") + scale_y_continuous(breaks = seq(0, 1, by = 0.1), labels = scales::percent) + coord_cartesian(xlim=c(0, 10), ylim=c(0, 1)) + scale_x_continuous(breaks = seq(0, 10, by = 1))
方法二:提前计算累积占比(更推荐)
手动对数据分箱、计算累积占比后再绘图,完全避免stat参数的差异问题:
library(ggplot2); library(dplyr) # 提前分箱并计算累积占比 df_stats <- df %>% mutate(bin = cut(col, breaks = 0:max(df$col, na.rm = T), include.lowest = TRUE)) %>% count(bin) %>% mutate( bin_start = as.numeric(sub("\\[(.*),.*\\]", "\\1", bin)), # 提取分箱左边界 cum_pct = cumsum(n / sum(n)) ) %>% filter(bin_start <= 10) # 只保留0-10区间的分箱 # 绘图 ggplot(df_stats, aes(x = bin_start)) + geom_col(aes(y = cum_pct), fill = "blue", color = "black", width = 1) + geom_line(aes(y = cum_pct, x = bin_start + 0.5), color = "red", size = 1) + scale_y_continuous(breaks = seq(0, 1, by = 0.1), labels = scales::percent) + scale_x_continuous(breaks = seq(0, 10, by = 1)) + coord_cartesian(ylim = c(0, 1))
调整后,红色累积线会和直方图的累积占比完全匹配,第一个柱的累积值为82%左右,逐步递增到95%(0-10区间的总占比)。
内容的提问来源于stack exchange,提问作者Julien
相关产品推荐
相关产品推荐

