在R中绘制数据框的堆叠柱状图(按类别而非计数配色)
解决堆叠柱状图的绘制问题
我懂你这种 frustration——本来以为画个堆叠柱状图很简单,结果现有代码要么不对要么出问题。咱们一步步把这个图给做对。
首先,先明确需求:X轴是a和b这两个分组,每个X轴柱子里堆叠foo、bar、spam这三个类别,用不同颜色区分。
原代码的核心问题
你原来的代码里,aes(fill=value)是关键错误——你把填充颜色映射给了数值value,而不是我们要堆叠的分类变量category,这就导致ggplot完全误解了你的堆叠逻辑,自然会出现异常。另外,melt的时候最好明确指定id.vars,避免数据重塑出问题。
正确的实现步骤
- 先构造测试数据框(方便你直接复现):
df <- data.frame( category = c("foo", "bar", "spam"), a = c(2, 1, 0), b = c(0, 1, 1) )
- 正确重塑数据:
用reshape2::melt时,指定id.vars = "category",这样能保证我们保留分类列,把a和b转成观测变量:
library(reshape2) library(ggplot2) df_melted <- melt(df, id.vars = "category")
- 绘制堆叠柱状图:
关键是把fill映射给category,X轴用variable(也就是a和b),Y轴用value,再用geom_bar(stat="identity")实现堆叠(默认position就是stack,也可以显式写出来更清晰):
ggplot(df_melted, aes(x = variable, y = value, fill = category)) + geom_bar(stat = "identity", position = "stack") + # 可选:美化坐标轴和图例标签 labs(x = "分组", y = "数值", fill = "类别")
- 可选:保留0值类别的图例
如果像你的数据里,foo在b组的数值是0、spam在a组的数值是0,默认ggplot会把这些没有数据的类别从图例里去掉。如果想让所有类别都留在图例里,可以加上scale_fill_discrete(drop = FALSE):
ggplot(df_melted, aes(x = variable, y = value, fill = category)) + geom_bar(stat = "identity", position = "stack") + labs(x = "分组", y = "数值", fill = "类别") + scale_fill_discrete(drop = FALSE)
这样画出来的图就完全符合你的需求了:X轴是a和b,每个柱子里按foo、bar、spam堆叠,颜色对应不同类别。
内容的提问来源于stack exchange,提问作者Liquidity
相关产品推荐
相关产品推荐

