ggplot2绘制发散堆叠条形图图例因子排序异常如何解决
我尝试使用ggplot2将李克特(Likert)量表数据绘制成发散堆叠条形图(divergent stacked bar chart)。
我查阅了多种解决方案,其中最适配的是分面实现方案(我不需要使用分面功能),该方案针对奇数级量表的中立选项可对齐0点居中的特性非常符合我的需求。
我对该方案的实现思路(使用两个geom_col()分别绘制正负向计数)做了简化复现,代码如下:
# 数据样例 data <- tibble( question = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "B"), option = c("Very bad", "Bad", "Neutral", "Good", "Exc", "Very bad", "Bad", "Neutral", "Good", "Exc"), count = c(1, 10, 4, 5, 3, 3, 4, 5, 6, 8) ) %>% mutate( option = option %>% factor(levels = c("Very bad", "Bad", "Neutral", "Good", "Exc")), count = if_else(option == "Neutral", count/2, count) ) # 绘制发散堆叠条形图 data %>% ggplot(aes(question, count, fill = option)) + geom_col(data = filter(data, option %in% c("Neutral", "Good", "Exc")), position = position_stack(reverse = T)) + geom_col(data = filter(data, option %in% c("Neutral", "Bad", "Very bad")), aes(y = -count)) + scale_fill_brewer(palette = "RdBu") + coord_flip()
运行代码后得到的结果如下:
可以看到图表的堆叠顺序是正确的,但图例和配色并没有遵循我设定的因子排序,就算给因子添加ordered = T参数也没有效果。
如果我删除第二个geom_col()图层,图例排序就会恢复正常,但这不符合我的绘图需求。
请问我该如何强制ggplot2在图例中保留我预设的因子排序?
问题原因
图例顺序错乱的核心原因是ggplot2默认会按照第一个绘图图层中出现的因子水平顺序生成图例。第一个geom_col仅包含Neutral、Good、Exc三个水平,第二个图层才补充了Bad、Very bad,因此图例顺序不会遵循预设的因子排序。
解决方案
只需要在scale_fill_brewer中添加limits参数,指定为已经设置好的因子水平即可,修改后的绘图代码如下:
data %>% ggplot(aes(question, count, fill = option)) + geom_col(data = filter(data, option %in% c("Neutral", "Good", "Exc")), position = position_stack(reverse = T)) + geom_col(data = filter(data, option %in% c("Neutral", "Bad", "Very bad")), aes(y = -count)) + # 新增limits参数,强制使用预设的因子顺序 scale_fill_brewer(palette = "RdBu", limits = levels(data$option)) + coord_flip()
limits参数会直接指定填充色映射的水平顺序,不受图层出现顺序的影响,同时配色也会按照预设的因子顺序对应到RdBu调色板的对应色阶。如果后续需要调整图例展示的标签,也可以搭配labels参数使用,不会影响排序效果。
内容的提问来源于stack exchange,提问作者iNyar
相关产品推荐
相关产品推荐

