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

如何在R的ggplot2雨云图中整合丰度加权物种丰富度信息?

问题描述

我需要可视化某区域两个年份的物种数据,包含物种性状值(1-12)与丰度(1-15),已用R的ggplot2绘制基础雨云图展示不同年份特定性状值的物种分布。现在希望在雨云图的云状部分整合丰度加权的物种丰富度信息(比如对应性状值的物种丰度总和或个体占比),但尝试stat_halfeye、stat_slab等函数均未成功,求可行实现方案。

简化数据集

df <- structure(list(Species.name = structure(c(1L, 4L, 5L, 6L, 7L, 
8L, 9L, 10L, 11L, 2L, 3L, 1L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 
2L, 3L), levels = c("Spec1", "Spec10", "Spec11", "Spec2", "Spec3", 
"Spec4", "Spec5", "Spec6", "Spec7", "Spec8", "Spec9"), class = "factor"), 
    Year = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), levels = c("2012", 
    "2013"), class = "factor"), Abundance = c(1, 1, 8, 1, 3, 
    2, 6, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), Presence = c(1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1), Trait.value = c(6, 4, 6, 9, 7, 10, 7, 4, 6, 8, 5, 
    6, 4, 6, 9, 7, 10, 7, 4, 6, 8, 5)), row.names = c(NA, -22L
), class = c("tbl_df", "tbl", "data.frame"))

已用包及数据预处理

library(ggplot2)
library(ggdist)

df$Species.name <- as.factor(df$Species.name)
df$Year <- as.factor(df$Year)
str(df)

基础雨云图代码

Trait_plot <- ggplot(df, aes(x = Year, y = Trait.value)) +
  ylim(0, 12) +
  stat_halfeye(adjust = 0.5, justification = -0.2, .width = 0, point_colour = NA) +
  geom_boxplot(width = 0.12, outlier.color = NA, alpha = 0.5) +
  stat_dots(side = "left", justification = 1.1, binwidth = 0.25) +
  guides(fill = FALSE) +
  theme_classic()
Trait_plot

尝试过的未成功代码示例

Trait_plot_statdens <- ggplot(df, aes(x = Year, y = Trait.value)) +
  ylim(0, 12) +
  stat_density(data = df, aes(x = Year, y = Trait.value), position = "jitter") +
  #stat_halfeye(adjust = 0.5, justification = -0.2, .width = 0, point_colour = NA) +
  geom_boxplot(width = 0.12, outlier.color = NA, alpha = 0.5) +
  stat_dots(side = "left", justification = 1.1, binwidth = 0.25) +
  guides(fill = FALSE) +
  theme_classic()
Trait_plot_statdens
解决方案

要实现丰度加权的云状分布,核心思路是先按年份和性状值聚合计算丰度权重,或直接用权重参数调整密度分布,以下是两种可行方案:

方案1:用stat_slab直接绑定丰度权重

ggdist的stat_slab支持通过weights参数传入丰度值,让密度计算时以物种丰度为权重,丰度高的物种会在对应性状值位置贡献更高的密度,直观体现个体占比分布:

# 加权雨云图:云状部分用丰度加权
Trait_plot_weighted <- ggplot(df, aes(x = Year, y = Trait.value)) +
  ylim(0, 12) +
  # 用stat_slab生成加权密度云状,weights绑定Abundance
  stat_slab(aes(weights = Abundance), adjust = 0.5, justification = -0.2, .width = 0, 
            fill = "gray70", color = NA) +
  geom_boxplot(width = 0.12, outlier.color = NA, alpha = 0.5) +
  stat_dots(side = "left", justification = 1.1, binwidth = 0.25) +
  guides(fill = FALSE) +
  theme_classic()
Trait_plot_weighted

如果要展示个体占比,可将weights设为按年份分组的相对丰度:weights = Abundance / sum(Abundance)。

方案2:先聚合数据再绘制丰度总和分布

若需要展示性状值对应的丰度总和,可先按年份和性状值分组求和,再基于聚合数据绘制云状图:

library(dplyr)

# 1. 聚合计算每个年份-性状值的丰度总和
df_agg <- df %>%
  group_by(Year, Trait.value) %>%
  summarise(total_abundance = sum(Abundance), .groups = "drop")

# 2. 绘制基于丰度总和的加权雨云图
Trait_plot_agg <- ggplot(df, aes(x = Year, y = Trait.value)) +
  ylim(0, 12) +
  # 用stat_density生成加权密度,weight关联聚合后的丰度总和
  stat_density(data = df_agg, aes(y = Trait.value, weight = total_abundance), 
               position = "identity", geom = "area", adjust = 0.5, 
               fill = "gray70", alpha = 0.7) +
  geom_boxplot(width = 0.12, outlier.color = NA, alpha = 0.5) +
  stat_dots(side = "left", justification = 1.1, binwidth = 0.25) +
  guides(fill = FALSE) +
  theme_classic()
Trait_plot_agg

这种方式可自定义聚合统计量,比如将total_abundance替换为total_abundance / sum(total_abundance)得到丰度占比。

关键注意点

  • 确保ggdist包为最新版本,旧版本对weights参数支持有限;
  • stat_halfeye本质是stat_slab+stat_pointinterval的组合,同样支持weights参数,可直接替换方案1中的stat_slab。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:39:54