ggplot2绘制dodge分组横向柱状图时调整柱体显示顺序方法咨询
问题背景
需要柱状图同时展示两类分组数据,构建了包含重复记录的数据集作为绘图输入,所用数据结构参考如下示例:

基于该数据编写的ggplot2绘图代码如下:
Select <- "Mbp" if(Select == "Mbp"){ Select <- "Amount of sequence (Mbp)" } else if (Select == "Gbp"){ Select <- "Amount of sequence (Gbp)" } ggplot(G4, aes(x = INDV, y = Bp, fill = Group)) + theme_light() + geom_bar(stat = 'identity', position = 'dodge', width = 0.6) + coord_flip() + scale_x_discrete(limits = rev(unname(unlist(RAW_TRIM[1])))) + scale_fill_discrete(breaks = c("Raw data","Trimmed data"))+ scale_y_continuous(labels = scales::comma, position = "right") + theme(axis.text = element_text(colour = "black", face = "bold", size = 15)) + theme(legend.position = "bottom", legend.text = element_text(face = "bold", size = 15), legend.title = element_blank()) + ggtitle(Select) + xlab("") + ylab("") + theme(plot.title = element_text(size = 25, face = "bold", hjust = 0.5))
运行代码得到的横向分组柱状图如下,当前绿色填充柱位于红色填充柱上层,目标是实现红色填充柱显示在绿色填充柱上层,此前尝试调整数据集排序等方案均未生效。
解决方案
之前调整无效的核心原因有两个:
scale_fill_discrete()里的breaks参数仅控制图例条目的显示顺序,完全不控制柱子的实际绘制渲染顺序- 仅调整数据框的行顺序没用,ggplot渲染分组几何对象时,会按照分组变量的因子水平顺序绘制,先画的柱子会被后画的柱子遮挡;如果分组变量是字符型,会默认按字母顺序自动转因子,不会随数据行顺序改变绘制顺序。
直接按以下任意一种方式修改即可实现效果:
方法1:提前调整分组变量的因子水平
在绘图代码运行前,将Group列转为因子,把需要放在上层(后渲染)的组放在因子水平的最后一位即可:
# 把要放在上层的红色对应组"Raw data"放在levels最后,后绘制就不会被遮挡 G4$Group <- factor(G4$Group, levels = c("Trimmed data", "Raw data"))
后续运行原绘图代码即可,不需要改动其他绘图逻辑,图例顺序可以保留原有设置不受影响。
方法2:在绘图映射内直接指定因子顺序(不修改原数据)
如果不想改动原数据框的结构,可以直接在aes()的fill映射里指定因子顺序,修改后完整代码如下:
Select <- "Mbp" if(Select == "Mbp"){ Select <- "Amount of sequence (Mbp)" } else if (Select == "Gbp"){ Select <- "Amount of sequence (Gbp)" } ggplot(G4, aes(x = INDV, y = Bp, fill = factor(Group, levels = c("Trimmed data", "Raw data")))) + theme_light() + # 把width参数挪到position_dodge内,避免分组错位 geom_bar(stat = 'identity', position = position_dodge(width = 0.6, preserve = "single"), width = 0.6) + coord_flip() + scale_x_discrete(limits = rev(unname(unlist(RAW_TRIM[1])))) + # 图例顺序保持原有设置,补充labels参数避免显示异常 scale_fill_discrete(breaks = c("Raw data","Trimmed data"), labels = c("Raw data","Trimmed data"))+ scale_y_continuous(labels = scales::comma, position = "right") + theme(axis.text = element_text(colour = "black", face = "bold", size = 15)) + theme(legend.position = "bottom", legend.text = element_text(face = "bold", size = 15), legend.title = element_blank()) + ggtitle(Select) + xlab("") + ylab("") + theme(plot.title = element_text(size = 25, face = "bold", hjust = 0.5))
内容的提问来源于stack exchange,提问作者NewB
相关产品推荐
相关产品推荐

