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

ggplot2绘制Likert图时自定义图例顺序不匹配绘图因子顺序的问题

解决方案

你遇到的图例与堆叠顺序不匹配问题,核心是ggplot2默认按value因子的原生level排序图例,和你设置的position_stack(reverse = TRUE)堆叠顺序不一致。你不需要修改原数据的因子结构,直接通过scale_fill_manual的breaks参数自定义图例顺序即可,不会影响现有图表的因子顺序和堆叠效果。

具体修改步骤

  1. 先给颜色向量命名,绑定每个类别对应的颜色,避免顺序调整后颜色错位:
col4 <- c(
  "Very Important" = "#81A88D",
  "Important" = "#ABDDDE",
  "Less Important" = "#F4B5BD",
  "Not at all Important" = "#B40F20",
  "Strongly Satisfied" = "orange",
  "Satisfied" = "#F3DF6C",
  "N/A" = "gray"
)
  1. 定义你需要匹配堆叠的图例顺序:
legend_order <- c("Very Important", "Important", "Less Important", "Not at all Important", "Strongly Satisfied", "Satisfied", "N/A")
  1. 修改原绘图代码的冗余柱状图层和scale_fill_manual配置:
  • 删掉重复的geom_bar和geom_col,保留一个带reverse参数的geom_col即可
  • 在scale_fill_manual中添加breaks参数指定上面定义的图例顺序

修改后完整可运行代码

library(ggplot2)

# 原数据集
df <- structure(list(Benefit = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 
3L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 
8L, 9L, 9L, 9L, 9L, 10L, 10L, 10L), .Label = c("Medical: Importance", 
"Medical:Satisfaction", "Dental:  Importance", "Dental: Satisfaction", 
"Vision:  Importance", "Vision: Satisfaction", "401K:    Importance", 
"401K:   Satisfaction", "EAP:     Importance", "EAP:    Satisfaction"
), class = "factor"), value = structure(c(1L, 2L, 5L, 6L, 1L, 
2L, 4L, 5L, 6L, 9L, 1L, 2L, 4L, 5L, 6L, 9L, 1L, 2L, 3L, 4L, 5L, 
6L, 9L, 1L, 2L, 3L, 4L, 5L, 6L, 9L), .Label = c("Very Important", 
"Important", "Not at all Important", "Less Important", "Strongly Satisfied", 
"Satisfied", "Strongly Dissatisfied", "Dissatisified", "N/A"), class = "factor"), 
    Percent = c(-80.7, -19.3, -50, -50, -64.3, -33.9, 1.8, -43.6, 
    -50.9, 5.5, -52.7, -41.8, 5.5, -33.9, -51.8, 14.3, -75, -17.3, 
    5.8, 1.9, -50, -30.8, 19.2, -13.7, -39.2, 5.9, 41.2, -13.2, 
    -45.3, 41.5)), class = "data.frame", row.names = c(4L, 9L, 
24L, 29L, 2L, 7L, 12L, 22L, 27L, 42L, 5L, 10L, 15L, 25L, 30L, 
45L, 1L, 6L, 16L, 11L, 21L, 26L, 41L, 3L, 8L, 18L, 13L, 23L, 
28L, 43L))

# 命名颜色向量,避免颜色错位
col4 <- c(
  "Very Important" = "#81A88D",
  "Important" = "#ABDDDE",
  "Less Important" = "#F4B5BD",
  "Not at all Important" = "#B40F20",
  "Strongly Satisfied" = "orange",
  "Satisfied" = "#F3DF6C",
  "N/A" = "gray"
)

# 自定义图例顺序,匹配堆叠顺序
legend_order <- c("Very Important", "Important", "Less Important", "Not at all Important", "Strongly Satisfied", "Satisfied", "N/A")

p <- ggplot(df, aes(x=Benefit, y = Percent, fill = value, label=abs(Percent))) +
  # 删掉冗余图层,保留单个geom_col即可
  geom_col(width = .5, position = position_stack(reverse = TRUE)) +
  scale_x_discrete(limits = rev(levels(df$Benefit))) +
  geom_text(position = position_stack(vjust = 0.5), 
            angle = 45, color="black") +
  coord_flip() +
  # 添加breaks参数自定义图例顺序
  scale_fill_manual(values = col4, breaks = legend_order) +
  scale_y_continuous(breaks=(seq(-100,100,25)), labels=abs(seq(-100,100,by=25)), limits=c(-100,100)) +
  theme_minimal() +
  theme(
    axis.title.y = element_blank(),
    legend.position = c(0.85, 0.8),
    legend.title=element_text(size=14), 
    axis.text=element_text(size=12, face="bold"),
    legend.text=element_text(size=12),               
    panel.background = element_rect(fill = "transparent",colour = NA),
    plot.background = element_rect(fill = "transparent",colour = NA),
    panel.grid.major=element_blank(),
    panel.grid.minor=element_blank()
  )+
  labs(fill="") + ylab("Percent") +
  annotate("text", x = 9.5, y = 50, label = "Importance") +
  annotate("text", x = 8.00, y = 50, label = "Satisfaction") 
p

内容的提问来源于stack exchange,提问作者JeniFav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:48:02