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
相关产品推荐
相关产品推荐

