ggplot分组直方图计数显示顺序与实际不符如何修正
问题原因
你遇到的显示偏差是因为geom_histogram默认使用**堆叠(position = "stack")**的位置布局:同一区间(bin)内不同pBu分组的柱子会逐层向上堆叠,上层分组的柱子顶部高度是「当前分组计数+所有下层分组计数」的总和,因此会出现计数更少的pBu=0.05柱子视觉上更高的误解。
解决方案
方案1:分组柱子并排展示(最直观,推荐)
修改geom_histogram的位置参数为position = "dodge",同一bin内的不同分组柱子会并排排列,各自的高度直接对应当前分组的计数,无需额外调整即可直接对比大小。
修改后代码如下:
EV <- (dt.test %>% dplyr::mutate(pBu = as.factor(pBu)) %>% ggplot(aes(x = EV)) + # 增加position = "dodge"参数 geom_histogram(aes(color = pBu), binwidth = 0.3, fill = "transparent", position = "dodge") + ggtitle("Histogram EV 2020") + ylab("Counts") + theme(panel.background = element_blank(), axis.line = element_line(colour = "black"), plot.title = element_text(lineheight = .8, hjust = 0.5, face = "bold"), legend.title = element_blank(), legend.background = element_rect(fill = "white", size = 0.5, linetype = "solid", colour ="black"), legend.box.background = element_rect(colour = "black"), legend.box.margin = margin(t = 1, l = 1)) ) %>% ggplotly()
方案2:保持重叠样式,调整因子顺序和位置参数
如果希望保留柱子重叠的展示效果,需要做两处调整:
- 将位置参数改为
position = "identity",让所有分组的柱子都从y轴0点开始绘制,高度直接对应当前分组计数 - 调整
pBu的因子顺序,让计数更高的分组优先绘制在上层,避免被遮挡;同时可给填充色加透明度优化重叠展示效果
修改后代码如下:
library(forcats) EV <- (dt.test %>% # 按计数频率从高到低排序因子水平 dplyr::mutate(pBu = fct_infreq(as.factor(pBu))) %>% ggplot(aes(x = EV)) + geom_histogram(aes(color = pBu, fill = pBu), binwidth = 0.3, position = "identity", alpha = 0.2) + # 半透明避免遮挡 ggtitle("Histogram EV 2020") + ylab("Counts") + theme(panel.background = element_blank(), axis.line = element_line(colour = "black"), plot.title = element_text(lineheight = .8, hjust = 0.5, face = "bold"), legend.title = element_blank(), legend.background = element_rect(fill = "white", size = 0.5, linetype = "solid", colour ="black"), legend.box.background = element_rect(colour = "black"), legend.box.margin = margin(t = 1, l = 1)) ) %>% ggplotly()
额外优化建议
你当前设置的binwidth = 0.3极小,而EV列数值跨度从-772到95万+,会生成大量空的或仅包含0值的窄柱子,不利于观察整体分布,可以根据需求适当调大bin宽度(例如设置为binwidth = 10000),可视化效果会更清晰。
内容的提问来源于stack exchange,提问作者Miko
相关产品推荐
相关产品推荐

