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

ggplot分组并列柱状图技术问题:合并坐标轴与保留0%值

问题描述

需要绘制每个group旁并列显示IT和PT两组的填充式柱状图,当前脚本如下:

ggplot(score, aes(group, IT, fill = stain)) +
    geom_bar(stat="identity", position = "fill")+  
      scale_y_continuous(labels = scales::percent_format()) +
    ggplot(score, aes(group, PT, fill = stain)) +
     geom_bar(stat="identity", position = "fill")+ 
    scale_fill_manual(values = c("#edae49", "#d1495b", "#00798c", "#30638e"))+
      scale_y_continuous(labels = scales::percent_format()) + 
     ggtitle("CD4") 

请问如何将PT和IT的柱状图合并到同一y轴?另外,如何在图中保留0%值,避免自动转为NA?

参考效果的代码(已添加中文注释):

# 设置group的因子顺序
score$group <- factor(score$group, levels=c("All_BrM", "Sync","Meta","Poly" ))
# 设置stain的因子顺序
score$stain <- factor(score$stain, levels=c("none", "<10%","10-40%",">40%" ))

# 绘制IT组填充柱状图
ggplot(score, aes(group, IT, fill = stain)) +
  geom_bar(stat="identity", position = "fill")+  
    scale_fill_manual(values = c("#ded9e2", "#c0b9dd", "#80a1d4", "#75c9c8"))+
    theme_prism(base_size = 9)+
    scale_y_continuous(labels = scales::percent_format()) +
    theme(legend.position = "none")+ 
    theme(axis.text.x  = element_text(size = 10, angle=50))+
# 绘制PT组填充柱状图
ggplot(score, aes(group, PT, fill = stain)) +
  geom_bar(stat="identity", position = "fill")+ 
    scale_fill_manual(values = c("#ded9e2", "#c0b9dd", "#80a1d4", "#75c9c8"))+
    scale_y_continuous(labels = scales::percent_format())  +            
    theme_prism(base_size = 9)+
    theme(axis.text.x  = element_text(size = 10, angle=50))  

解决方案

1. 合并到同一y轴:将宽格式数据转为长格式

当前数据是宽格式(IT和PT为单独列),要实现同一y轴下group旁并列显示IT和PT,需先将数据转换为长格式,新增一列区分IT/PT类别,再通过分面或分组实现并列,同时保留填充比例逻辑。

2. 保留0%值:提前处理NA值

若原始数据中0被自动转为NA,需提前将NA替换为0;position = "fill"会自动计算比例,只要原始值为0,就能保留0%的显示。

完整代码示例

# 加载所需包
library(ggplot2)
library(tidyr)
library(dplyr)
library(ggprism)

# 数据预处理:设置因子顺序+转长格式+替换NA为0
score <- score %>%
  mutate(
    # 固定group和stain的显示顺序
    group = factor(group, levels=c("All_BrM", "Sync","Meta","Poly")),
    stain = factor(stain, levels=c("none", "<10%","10-40%",">40%")),
    # 将IT、PT列中的NA替换为0,确保0%值不丢失
    IT = ifelse(is.na(IT), 0, IT),
    PT = ifelse(is.na(PT), 0, PT)
  ) %>%
  # 把宽格式转长格式,新增type列标记IT/PT
  pivot_longer(cols = c(IT, PT), names_to = "type", values_to = "value")

# 绘制合并后的填充柱状图
ggplot(score, aes(x = group, y = value, fill = stain)) +
  # 填充式柱状图,保持每个柱子高度为100%
  geom_bar(stat = "identity", position = position_fill(), width = 0.7) +
  # 通过分面实现IT和PT在同一group旁并列,共享y轴
  facet_grid(~type) +
  # 设置自定义填充色
  scale_fill_manual(values = c("#edae49", "#d1495b", "#00798c", "#30638e")) +
  # y轴显示百分比,去掉上下空白
  scale_y_continuous(labels = scales::percent_format(), expand = c(0, 0)) +
  # 应用prism主题
  theme_prism(base_size = 9) +
  ggtitle("CD4") +
  # 调整轴文本和图例位置
  theme(
    axis.text.x = element_text(size = 10, angle = 50, hjust = 1),
    legend.position = "right"
  )

代码说明

  • pivot_longer():将IT、PT两列合并为一列,新增type列区分组别,是实现同一图中并列展示的核心步骤。
  • ifelse(is.na(IT), 0, IT):强制把NA转为0,避免0%值被自动过滤。
  • position_fill():维持填充式柱状图的比例逻辑,每个柱子总高度对应100%。
  • facet_grid(~type):通过分面让IT和PT在每个group旁并列,且共享同一y轴刻度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:20:48