R语言ggplot2调整直方图堆叠条形的上下排列顺序
调整ggplot直方图堆叠顺序
需求说明
绘制行驶距离相关直方图时,按剩余行驶距离将数据分为三类着色:
<0km:未抵达目的地,对应数据中Group=-1=0km:抵达目的地,对应数据中Group=0>0km:超出目的地范围,对应数据中Group=+1
当前绘图中间0值附近的堆叠条形顺序不符合要求,目标堆叠规则为:
- 绿色条(
=0km组)置于最底层,和其余区域同色条位置相邻 - 蓝色条(
<0km组)位于中间层 - 红色条(
>0km组)置于最顶层
最小可复现数据
df <- structure(list(excess_distance_km = c(87.5, 27.8, 18, 22.3, 35, 120.6, -0.3, 0, 0, 24.6, -0.2, 2.9, 2.9, 8.7, 27.6, 32.9, 32.9, 0, -0.2, -52.3, 54.4, 64.2, 64.2, 64.2, 50.2, 43.5, -13.5, -17.6, 82.1, 82.1, 0, 74, 34.9, 35.2, 0, 2, -11.4, 0, 2.5, -52.3, 68.1, 18, 0, 74.5, 29.6, 0.2, 18.9, 0, 0.7, 1.4), Group = c("+1", "+1", "+1", "+1", "+1", "+1", "-1", "0", "0", "+1", "-1", "+1", "+1", "+1", "+1", "+1", "+1", "0", "-1", "-1", "+1", "+1", "+1", "+1", "+1", "+1", "-1", "-1", "+1", "+1", "0", "+1", "+1", "+1", "0", "+1", "-1", "0", "+1", "-1", "+1", "+1", "0", "+1", "+1", "+1", "+1", "0", "+1", "+1")), row.names = c(NA, -50L), class = "data.frame")
当前使用代码
df %>% ggplot( aes(x = excess_distance_km)) + geom_histogram(aes(fill = Group), binwidth=5, alpha=0.9, colour = "grey25") + ggtitle("Excess Distance") + theme_classic() + theme(plot.title = element_text(size=15, hjust = 0.5), axis.title = element_text(size=12, hjust = 0.5), legend.text = element_text(size=12), legend.title = element_blank(), legend.position = "bottom" ) + guides(fill = guide_legend(nrow = 3))
当前运行效果

解决方法
ggplot2 中填充几何对象的堆叠顺序由映射到fill的变量的因子水平顺序决定:因子中排在最前的水平位于堆叠最底层(紧贴坐标轴),排在最后的水平位于堆叠最顶层。
原数据中Group是字符型,默认按字符串字典序排序,导致堆叠顺序不符合要求。只需提前将Group转为指定水平顺序的因子即可,修改后完整代码如下:
library(tidyverse) df %>% # 手动指定因子水平,顺序为:最底层 -> 中间层 -> 最顶层 mutate(Group = factor(Group, levels = c("0", "-1", "+1"))) %>% ggplot(aes(x = excess_distance_km)) + geom_histogram(aes(fill = Group), binwidth=5, alpha=0.9, colour = "grey25") + # 可选:手动指定颜色和标签,和三类语义完全匹配 # scale_fill_manual( # values = c("0" = "#2ca02c", "-1" = "#1f77b4", "+1" = "#d62728"), # labels = c("0" = "=0km(抵达目的地)", "-1" = "<0km(未抵达目的地)", "+1" = ">0km(超出目的地范围)") # ) + ggtitle("Excess Distance") + theme_classic() + theme(plot.title = element_text(size=15, hjust = 0.5), axis.title = element_text(size=12, hjust = 0.5), legend.text = element_text(size=12), legend.title = element_blank(), legend.position = "bottom" ) + guides(fill = guide_legend(nrow = 3))
修改后绿色的抵达组会固定在堆叠最底层,和左右两侧的绿色条保持连续,中间为蓝色未抵达组,最上层为红色超出组,完全符合预期顺序。
内容的提问来源于stack exchange,提问作者ltong
相关产品推荐
相关产品推荐

