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

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在下),且不打乱原有堆叠逻辑,可按以下步骤操作:

  1. 给不同等级设置正负数值
    先通过数据处理,给A、B等级保留正值,C、D等级设为负值,以此控制条形的上下方向:
library(dplyr)

DF <- DF %>%
  mutate(y = case_when(
    variable %in% c("A", "B") ~ value,
    variable %in% c("C", "D") ~ -value
  ))
  1. 绘制双方向堆叠条形图
    使用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))
  1. 关键逻辑说明
  • position_stack(reverse = FALSE)确保A在B上方(正值堆叠从下往上累加,A的数值会叠在B之上);C、D为负值,堆叠从X轴往下累加,自然呈现C在上、D在下的顺序。
  • 原代码中全局设置y = -value导致整体堆叠反转,现在通过分等级设置正负值,精准控制了上下方向的堆叠逻辑。
  • 文本位置的vjust=0.5无需区分正负,position_stack会自动计算每个堆叠块的中心位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 10:02:54