如何在R ggplot2中按actings_corps_descriptions分面生成分组条形图
在R中按字段分面实现2列5行布局的分组条形图
需求说明
我有如下数据集,希望按actings_corps_description字段分面创建分组条形图,数据集共有10个不同的actings_corps_description值,需要实现2列5行的布局。以下是单个分类的绘图代码和数据集示例:
单个分类绘图代码
final_res %>% dplyr::filter(actings_corps_description == "BOC-Gerrink") %>% ggplot2::ggplot(ggplot2::aes(fill = ropple_bucket, x = pos_bucket , y = n)) + ggplot2::geom_bar(position="dodge", stat="identity") + ggplot2::geom_text(ggplot2::aes(label = freq), position = ggplot2::position_dodge(width = 0.9), size = 2.5, family = 'sans', fontface = 'bold') + ggplot2::ggtitle('Relationship between Position and Ropple') + ggplot2::labs(y = 'n', x = 'Average Position Bucket') + ggplot2::guides(fill = ggplot2::guide_legend(title='Ropple Bucket'))
数据集示例
actings_corps_description ropple_bucket pos_bucket n freq <chr> <chr> <chr> <int> <dbl> 1 BOC-Gerrink 0-200 0-25 54 0.931 2 BOC-Gerrink 0-200 26-50 368 0.906 3 BOC-Gerrink 0-200 51-75 266 0.989 4 BOC-Gerrink 0-200 75+ 13 1 5 BOC-Gerrink 201-400 0-25 3 0.052 6 BOC-Gerrink 201-400 26-50 33 0.081 7 BOC-Gerrink 201-400 51-75 3 0.011 8 BOC-Gerrink 401-600 0-25 1 0.017 9 BOC-Gerrink 401-600 26-50 5 0.012 10 KND-Initial AB Issues 0-200 0-25 290 0.871 11 KND-Initial AB Issues 0-200 26-50 2840 0.884 12 KND-Initial AB Issues 0-200 51-75 1561 0.982 13 KND-Initial AB Issues 0-200 75+ 16 0.889 14 KND-Initial AB Issues 201-400 0-25 35 0.105 15 KND-Initial AB Issues 201-400 26-50 342 0.106 16 KND-Initial AB Issues 201-400 51-75 28 0.018 17 KND-Initial AB Issues 201-400 75+ 2 0.111 18 KND-Initial AB Issues 401-600 0-25 8 0.024 19 KND-Initial AB Issues 401-600 26-50 31 0.01 20 KND-Initial AB Issues 600+ 26-50 1 0
解决方案
直接使用ggplot2的facet_wrap()函数即可实现分面布局,无需逐个过滤绘图,具体代码如下:
核心实现代码
library(dplyr) library(ggplot2) final_res %>% ggplot(aes(fill = ropple_bucket, x = pos_bucket, y = n)) + geom_bar(position = "dodge", stat = "identity") + geom_text(aes(label = freq), position = position_dodge(width = 0.9), size = 2, # 缩小文字避免子图内重叠 family = 'sans', fontface = 'bold') + labs(y = 'n', x = 'Average Position Bucket') + guides(fill = guide_legend(title='Ropple Bucket')) + # 关键:按actings_corps_description分面,指定2列5行 facet_wrap(~ actings_corps_description, ncol = 2, nrow = 5) + # 可选:调整主题,让子图布局更紧凑 theme_bw() + theme( strip.text = element_text(size = 10, face = "bold"), # 子图标题样式 axis.text.x = element_text(angle = 45, hjust = 1), # X轴标签旋转避免重叠 legend.position = "bottom" # 图例放底部,节省子图空间 )
关键说明
- 去掉
filter():facet_wrap()会自动按actings_corps_description的不同值分组生成子图,无需手动过滤单个分类。 facet_wrap()参数:ncol = 2指定列数为2,nrow = 5指定行数为5,刚好匹配10个分类的布局需求。- 优化细节:
- 缩小
geom_text的size,避免子图内文字重叠; - 旋转X轴标签并调整对齐方式,防止长标签互相遮挡;
- 将图例移至底部,减少子图的垂直空间占用;
- 使用
theme_bw()让图表风格更清爽,子图标题加粗突出分类名称。
- 缩小
内容的提问来源于stack exchange,提问作者Eisen
相关产品推荐
相关产品推荐

