ggplot2绘制Likert图时自定义图例顺序不匹配绘图因子顺序的问题
解决方案
你遇到的图例与堆叠顺序不匹配问题,核心是ggplot2默认按value因子的原生level排序图例,和你设置的position_stack(reverse = TRUE)堆叠顺序不一致。你不需要修改原数据的因子结构,直接通过scale_fill_manual的breaks参数自定义图例顺序即可,不会影响现有图表的因子顺序和堆叠效果。
具体修改步骤
- 先给颜色向量命名,绑定每个类别对应的颜色,避免顺序调整后颜色错位:
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")
- 修改原绘图代码的冗余柱状图层和
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
相关产品推荐
相关产品推荐

