R ggplot2绘制同x轴多y值类facet_wrap效果分面条形图方法
ggplot2 绘制固定x轴多列数据的分面条形图
核心说明
- 你的判断是对的:
geom_bar()默认执行计数统计,自动统计每个x值的出现次数,适合原始明细数据;已经提前计算好y值的场景要用geom_col(),它会直接读取数据中映射给y的数值,不做额外计算。 - ggplot2 不支持直接将多列同时映射为同一x轴下的独立y序列,必须先将宽格式数据转换为长格式,把D0-D4的列名收拢为分组字段、对应数值收拢为统一的y值字段,才能实现分面效果。
实现代码
1. 加载依赖包
library(ggplot2) library(tidyr) # 用来做长宽表转换
2. 转换数据格式
把原宽表转为ggplot2适配的长表:
freq_dist_long <- pivot_longer( freq_dist, cols = D0:D4, # 选中需要绘图的D0到D4列 names_to = "group", # 新列存原列名(D0/D1/D2/D3/D4)作为分组依据 values_to = "count" # 新列存原表中对应的y轴数值 )
转换后的长表每一行对应一个Duration下某一个分组的数值,结构示例:
| Duration | group | count |
|---|---|---|
| 1 | D0 | 130 |
| 1 | D1 | 101 |
| 1 | D2 | 53 |
| 1 | D3 | 30 |
| 1 | D4 | 10 |
| 2 | D0 | 23 |
| 2 | D1 | 36 |
3. 绘图
ggplot(freq_dist_long, aes(x = factor(Duration), y = count)) + geom_col(fill = "#4e79a7") + facet_wrap(~group, nrow = 1) + # 按D0-D4分组分面,可调整nrow/ncol改分面排版 labs(x = "Duration", y = "数值") + theme_minimal()
可选调整
- 如果不需要分面,想做同坐标系下的并排分组条形,删掉
facet_wrap行,在aes中加fill映射即可:
ggplot(freq_dist_long, aes(x = factor(Duration), y = count, fill = group)) + geom_col(position = position_dodge(width = 0.8), width = 0.7) + labs(x = "Duration", y = "数值", fill = "分组") + theme_minimal()
- 代码里用
factor(Duration)是为了让x轴按离散值展示,避免Duration被识别为连续数值出现多余的小数刻度,和基础包barplot(yy~xx)的轴效果一致。 - 如果只需要绘制单列(比如仅D0),可以不转换数据直接写:
ggplot(freq_dist, aes(x = factor(Duration), y = D0)) + geom_col(),但多列场景下长格式的写法可维护性更高。
内容的提问来源于stack exchange,提问作者YinLong Huang
相关产品推荐
相关产品推荐

