如何在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
相关产品推荐
相关产品推荐

