ggplot2堆叠条形图:移部分堆叠至X轴下方后顺序错乱问题
问题描述
我有一个记录多所学校学生考试成绩等级(A至D)占比的数据框DF,结构如下:
str(DF) 'data.frame': 244 obs. of 3 variables: $ School: Factor w/ 61 levels $ variable: Factor w/ 4 levels "A","B","C","D" $ value : num 22.4 29.8 16.7 35.1 23.6 ...
(School列为因子类型,可按特定顺序绘图)
我用以下ggplot2代码绘制了堆叠顺序正确的条形图(A在顶部、D在底部):
ggplot(DF, aes(x = School, y = -value, fill = variable)) + geom_bar(stat = "identity") + scale_fill_manual(values=paleta, labels = etiquetas)+ geom_text(aes(label = paste0(round(value), "%")), position = position_stack(vjust = 0.5), size = 2, color = "black") + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1))+ theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1), axis.text.y = element_blank(), panel.grid.major.y = element_blank(), panel.grid.minor.y = element_blank(), legend.position = "bottom")+ guides(fill = guide_legend(reverse = TRUE))+ scale_x_discrete(labels = function(x) str_sub(x, end = 20))
现在想把C、D等级的占比移到X轴下方,但尝试多种方法后都会破坏堆叠顺序,X轴上方的堆叠会反转成A在底部、B在顶部。
解决方案
要实现A、B在X轴上方(保持A在上、B在下的堆叠顺序),C、D在X轴下方(C在上、D在下),且不打乱原有堆叠逻辑,可按以下步骤操作:
- 给不同等级设置正负数值
先通过数据处理,给A、B等级保留正值,C、D等级设为负值,以此控制条形的上下方向:
library(dplyr) DF <- DF %>% mutate(y = case_when( variable %in% c("A", "B") ~ value, variable %in% c("C", "D") ~ -value ))
- 绘制双方向堆叠条形图
使用position_stack()精准控制堆叠顺序,同时保持文本和图例的正确显示:
library(ggplot2) library(stringr) ggplot(DF, aes(x = School, y = y, fill = variable)) + geom_col(position = position_stack(reverse = FALSE)) + scale_fill_manual(values = paleta, labels = etiquetas) + # 确保文本在每个堆叠块的中心位置 geom_text(aes(label = paste0(round(value), "%")), position = position_stack(vjust = 0.5), size = 2, color = "black") + theme_minimal() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1), axis.text.y = element_blank(), panel.grid.major.y = element_blank(), panel.grid.minor.y = element_blank(), legend.position = "bottom") + # 保持图例顺序为A、B、C、D guides(fill = guide_legend(reverse = FALSE)) + scale_x_discrete(labels = function(x) str_sub(x, end = 20))
- 关键逻辑说明
position_stack(reverse = FALSE)确保A在B上方(正值堆叠从下往上累加,A的数值会叠在B之上);C、D为负值,堆叠从X轴往下累加,自然呈现C在上、D在下的顺序。- 原代码中全局设置
y = -value导致整体堆叠反转,现在通过分等级设置正负值,精准控制了上下方向的堆叠逻辑。 - 文本位置的
vjust=0.5无需区分正负,position_stack会自动计算每个堆叠块的中心位置。
内容的提问来源于stack exchange,提问作者Mateo Canziani
相关产品推荐
相关产品推荐

