如何消除ggplot2+plotly堆叠条形图的分段空白?
问题描述
我用plotly和ggplot2制作交互式堆叠条形图,分析不同plant_species(X轴)吸引的bee_species(堆叠分类),但堆叠条形里出现了不属于任何蜂种的空白区域,而且图表没统计到Hylaeus modestus。以下是数据清洗、绘图代码,以及筛选Trifolium pratense的部分数据样本:
# 导入库 library(ggplot2) library(plotly) library(dplyr) # 数据清洗 data <- data %>% filter(plant_species != "None", bee_species != "None", nonnative_bee != "null") %>% select(-c("species_num","site","sampling","specialized_on","status")) native_bee_data <- data %>% filter(nonnative_bee == 0) %>% group_by(sample_id, plant_species) nonnative_bee_data <- data %>% filter(nonnative_bee == 1) %>% group_by(sample_id, plant_species) # 可视化各植物吸引的本地蜂种数量 ggplotly( ggplot(native_bee_data, aes(x = plant_species, fill = bee_species, stat = "count")) + geom_bar(position = "stack") + theme(axis.text.x = element_text(angle = 45, hjust=1)) + guides(fill = guide_legend(title = "Bee Species")) + labs(title = "Number of Native Bee Species Attracted to Each Plant Species") )
数据样本(Trifolium pratense筛选结果)
| sample_id | plant_species | bee_species | nonnative_bee |
|---|---|---|---|
| 17429 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17429 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17429 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17429 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17429 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17433 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17437 | Trifolium pratense | Bombus griseocollis | 0 |
| 17441 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17441 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17441 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17441 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17445 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17445 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17445 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17445 | Trifolium pratense | Bombus bimaculatus | 0 |
| 17452 | Trifolium pratense | Lasioglossum coreopsis | 0 |
| 17461 | Trifolium pratense | Hylaeus modestus | 0 |
| 17465 | Trifolium pratense | Calliopsis andreniformis | 0 |
| 17465 | Trifolium pratense | Lasioglossum hitchensi | 0 |
| 17473 | Trifolium pratense | Halictus poeyi/ligatus | 0 |
| 17473 | Trifolium pratense | Bombus impatiens | 0 |
原因分析
- 分组逻辑错误:你按
sample_id和plant_species分组,但后续绘图未使用分组统计结果,ggplot的stat="count"会基于原始行计数,但分组后的数据结构会让ggplot保留分组维度,导致部分蜂种在某些分组下计数为0,从而生成空白堆叠区域。 - 未提前聚合数据:直接用原始数据绘图,没有先按
plant_species和bee_species统计总数量,当某个蜂种在某株植物的部分样本中无记录时,会被视为0值,产生空白。 Hylaeus modestus未显示:该蜂种仅在单个样本中出现一次,分组后被分散到sample_id维度下,ggplot计数时可能因分组维度导致其未被正确统计。
解决方法
提前聚合数据,按plant_species和bee_species统计总数量,再用聚合后的数据绘图,避免分组带来的0值问题:
# 导入库 library(ggplot2) library(plotly) library(dplyr) # 数据清洗 data <- data %>% filter(plant_species != "None", bee_species != "None", nonnative_bee != "null") %>% select(-c("species_num","site","sampling","specialized_on","status")) # 聚合本地蜂数据:按植物和蜂种统计总数量 native_bee_data <- data %>% filter(nonnative_bee == 0) %>% group_by(plant_species, bee_species) %>% summarise(count = n(), .groups = "drop") # 聚合后取消分组,避免ggplot继承分组结构 # 绘制交互式堆叠条形图 ggplotly( ggplot(native_bee_data, aes(x = plant_species, y = count, fill = bee_species)) + geom_col(position = "stack") + # 用geom_col替代geom_bar,适配预聚合的数值 theme(axis.text.x = element_text(angle = 45, hjust=1)) + guides(fill = guide_legend(title = "蜂种")) + labs(title = "本地蜂种受各植物吸引数量统计", x = "植物种类", y = "蜂种个体数量") )
关键修改说明
- 替换分组维度:改为按
plant_species和bee_species分组,直接统计每个植物-蜂种组合的总个体数。 - 使用
geom_col:替代geom_bar,因为geom_col适用于已有数值变量的场景,避免重复计数。 - 取消分组:聚合后用
.groups = "drop"清除分组结构,防止ggplot继承分组导致的异常。
内容的提问来源于stack exchange,提问作者Levi Banks
相关产品推荐
相关产品推荐

