Position_dodge未正常工作:如何实现单货币三分组柱状图?
问题描述
我想制作一个柱状图,让每种货币对应三个柱形(CV_before、CV_after、CV_all),但当前代码生成的图表里每种货币只显示一个柱形,搜了一圈没找到可行办法。
我的代码
ggplot(data = CV_before_after_Covid19) + geom_col(mapping = aes(x = currency, y = CV_before, fill = "CV_before"), position = position_dodge(width = 0.5)) + geom_col(mapping = aes(x = currency, y = CV_after, fill = "CV_after"), position = position_dodge(width = 0.5)) + geom_col(mapping = aes(x = currency, y = CV_all, fill = "CV_all"), position = position_dodge(width = 0.5)) + scale_fill_manual(values = c("CV_before" = "red", "CV_after" = "blue", "CV_all" = "purple")) + xlab("Currency") + ylab("Coefficient of variation") + ggtitle("Grouped Bar Chart of CV for currencies Before and After COVID-19")
我的数据
| currency | CV_all | CV_before | CV_after |
|---|---|---|---|
| CNY_X | 0.04054334 | 0.03803299 | 0.041694824 |
| EUR_X | 0.05526912 | 0.03501674 | 0.062215616 |
| IDR_X | 0.03558016 | 0.02886830 | 0.036147174 |
| INR_X | 0.05557534 | 0.03831957 | 0.038223465 |
| JPY_X | 0.09165166 | 0.01969833 | 0.108483693 |
| KHR_X | 0.01056078 | 0.01396010 | 0.009620803 |
| KRW_X | 0.06563164 | 0.03785110 | 0.066604745 |
| MMK_X | 0.14419264 | 0.05973349 | 0.160856857 |
| SGD_X | 0.01980122 | 0.01577686 | 0.021311649 |
解决方案
你的问题出在数据格式上——ggplot的分组柱状图需要长格式数据,而你现在用的是宽格式(每个指标单独一列)。直接叠加geom_col会让三个柱形重叠在同一个x轴位置,所以看起来只有一个柱。
解决步骤:
- 用
tidyr包的pivot_longer把宽数据转成长数据,把CV_before、CV_after、CV_all合并成一列(命名为cv_type),对应数值放在另一列(命名为cv_value)。 - 只用一次
geom_col,通过fill = cv_type区分分组,配合position = position_dodge()实现柱形并排。
完整代码:
# 加载所需包 library(ggplot2) library(tidyr) # 转换数据格式 CV_long <- pivot_longer(CV_before_after_Covid19, cols = c(CV_before, CV_after, CV_all), names_to = "cv_type", values_to = "cv_value") # 绘制分组柱状图 ggplot(data = CV_long) + geom_col(mapping = aes(x = currency, y = cv_value, fill = cv_type), position = position_dodge(width = 0.8)) + scale_fill_manual(values = c("CV_before" = "red", "CV_after" = "blue", "CV_all" = "purple")) + xlab("货币") + ylab("变异系数") + ggtitle("新冠疫情前后各货币变异系数分组柱状图") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # 可选:旋转x轴标签避免重叠
关键说明
pivot_longer把宽数据转成了长数据,每一行对应一个货币的一个CV指标,让ggplot能识别分组逻辑。position_dodge(width = 0.8)控制同组柱形的间距,可根据视觉效果调整数值。- 最后添加的
theme是优化x轴标签可读性的可选操作,避免标签重叠。
内容的提问来源于stack exchange,提问作者stark02
相关产品推荐
相关产品推荐

