You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()

运行代码后得到的结果如下:
Ggplot divergent stacked bar chart

可以看到图表的堆叠顺序是正确的,但图例和配色并没有遵循我设定的因子排序,就算给因子添加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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 01:57:00