You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何消除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_idplant_speciesbee_speciesnonnative_bee
17429Trifolium pratenseBombus bimaculatus0
17429Trifolium pratenseBombus bimaculatus0
17429Trifolium pratenseBombus bimaculatus0
17429Trifolium pratenseBombus bimaculatus0
17429Trifolium pratenseBombus bimaculatus0
17433Trifolium pratenseBombus bimaculatus0
17437Trifolium pratenseBombus griseocollis0
17441Trifolium pratenseBombus bimaculatus0
17441Trifolium pratenseBombus bimaculatus0
17441Trifolium pratenseBombus bimaculatus0
17441Trifolium pratenseBombus bimaculatus0
17445Trifolium pratenseBombus bimaculatus0
17445Trifolium pratenseBombus bimaculatus0
17445Trifolium pratenseBombus bimaculatus0
17445Trifolium pratenseBombus bimaculatus0
17452Trifolium pratenseLasioglossum coreopsis0
17461Trifolium pratenseHylaeus modestus0
17465Trifolium pratenseCalliopsis andreniformis0
17465Trifolium pratenseLasioglossum hitchensi0
17473Trifolium pratenseHalictus poeyi/ligatus0
17473Trifolium pratenseBombus impatiens0

原因分析
  • 分组逻辑错误:你按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 = "蜂种个体数量")
)

关键修改说明

  1. 替换分组维度:改为按plant_species和bee_species分组,直接统计每个植物-蜂种组合的总个体数。
  2. 使用geom_col:替代geom_bar,因为geom_col适用于已有数值变量的场景,避免重复计数。
  3. 取消分组:聚合后用.groups = "drop"清除分组结构,防止ggplot继承分组导致的异常。

内容的提问来源于stack exchange,提问作者Levi Banks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:29:53