如何使用ggplot2绘制嵌套条形图?
用ggplot2绘制嵌套条形图的完整指南
嘿,我来一步步带你搞定用ggplot2绘制嵌套条形图——不管是堆叠式还是并列分组的,都给你讲得明明白白!
1. 先准备好合适的数据
ggplot2天生偏爱长格式数据,所以你得至少准备三个核心变量:
- 主类别(比如年份、部门)
- 子类别(比如产品、团队)
- 要可视化的数值(比如销售额、人数)
我给你构造一个示例数据集,一看就懂:
library(tibble) # 构造长格式数据:年份(主类别)、产品(子类别)、销售额(数值) nested_data <- tibble( Year = rep(c("2021", "2022", "2023"), each = 3), Product = rep(c("A", "B", "C"), 3), Sales = c(120, 80, 90, 150, 100, 110, 180, 130, 140) )
2. 加载必备的包
核心就是ggplot2,如果需要处理数据,还可以配上dplyr:
library(ggplot2) # 如果要排序或清洗数据,加载dplyr # library(dplyr)
3. 基础款:堆叠式嵌套条形图
这是最常用的嵌套形式——每个主类别条形里,堆叠显示子类别的数值占比。代码超简单:
ggplot(nested_data, aes(x = Year, y = Sales, fill = Product)) + geom_bar(stat = "identity")
aes()里:x绑定主类别,y绑定数值,fill用子类别区分颜色geom_bar(stat = "identity"):因为我们已经有现成的数值了,不需要统计计数,所以用identity
4. 另一种常用款:并列分组式嵌套
如果不想堆叠,而是让每个主类别下的子类别条形并列展示,只需要加个position参数:
ggplot(nested_data, aes(x = Year, y = Sales, fill = Product)) + geom_bar(stat = "identity", position = position_dodge(width = 0.8))
position_dodge(width = 0.8):控制并列条形的间距,0.8是默认值,你可以根据图表宽度调整(比如改成0.7让条形更紧凑)
5. 优化细节:让图表更专业
5.1 给条形加数值标签
光有条形不够,把数值标上去更清晰:
# 堆叠式的标签(放在每个堆叠块的中间) ggplot(nested_data, aes(x = Year, y = Sales, fill = Product)) + geom_bar(stat = "identity") + geom_text(aes(label = Sales), position = position_stack(vjust = 0.5)) # 并列式的标签(放在条形上方) ggplot(nested_data, aes(x = Year, y = Sales, fill = Product)) + geom_bar(stat = "identity", position = position_dodge(width = 0.8)) + geom_text(aes(label = Sales), position = position_dodge(width = 0.8), vjust = -0.5)
position_stack(vjust = 0.5):让标签垂直居中在堆叠块里vjust = -0.5:把标签往上挪,避免和条形重叠
5.2 自定义颜色和主题
默认颜色太单调?换个配色,再整个清爽的主题:
ggplot(nested_data, aes(x = Year, y = Sales, fill = Product)) + geom_bar(stat = "identity", position = position_dodge(width = 0.8)) + geom_text(aes(label = Sales), position = position_dodge(width = 0.8), vjust = -0.5) + # 自定义填充色 scale_fill_manual(values = c("#FF6B6B", "#4ECDC4", "#45B7D1")) + # 用极简主题替代默认主题 theme_minimal() + # 添加标题、轴标签和图例标题 labs(title = "2021-2023年产品销售额对比", x = "年份", y = "销售额(万元)", fill = "产品类别")
5.3 按数值排序子类别
如果想让子类别按销售额从高到低排列,先给数据排个序:
library(dplyr) # 按年份分组,按销售额降序排列,再把Product转成因子(固定顺序) sorted_data <- nested_data %>% arrange(Year, desc(Sales)) %>% mutate(Product = factor(Product, levels = unique(Product))) # 用排序后的数据绘图 ggplot(sorted_data, aes(x = Year, y = Sales, fill = Product)) + geom_bar(stat = "identity", position = position_dodge(width = 0.8)) + geom_text(aes(label = Sales), position = position_dodge(width = 0.8), vjust = -0.5) + scale_fill_manual(values = c("#FF6B6B", "#4ECDC4", "#45B7D1")) + theme_minimal()
6. 进阶玩法:双重嵌套(分面+堆叠)
如果需要更复杂的嵌套(比如主类别→子类别→更细的类别),可以用分面+堆叠组合:
# 构造双重嵌套数据:年份→产品→区域 double_nested_data <- tibble( Year = rep(c("2021", "2022", "2023"), each = 6), Product = rep(rep(c("A", "B", "C"), each = 2), 3), Region = rep(c("North", "South"), 9), Sales = c(60,60,40,40,45,45,75,75,50,50,55,55,90,90,65,65,70,70) ) # 按产品分面,每个分面里展示年份+区域的堆叠条形 ggplot(double_nested_data, aes(x = Year, y = Sales, fill = Region)) + geom_bar(stat = "identity", position = position_stack()) + facet_wrap(~Product) + theme_minimal() + labs(title = "各产品分区域年度销售额", x = "年份", y = "销售额", fill = "区域")
如果还有细节想调整,比如把图例移到顶部、调整坐标轴字体大小,都可以用theme()函数定制,比如theme(legend.position = "top", axis.text.x = element_text(angle = 45, hjust = 1))。
内容的提问来源于stack exchange,提问作者SentientProgram
相关产品推荐
相关产品推荐

