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

如何在分面的geom_density图中添加合并的总密度曲线?

问题描述

我想要绘制甲虫在4个不同区域内停留时间占比的密度图,另有一个包含2个水平的日间时段(Time)分类变量。目前已通过facet_wrap按Habitat分面,并按Time对占比数据分组绘制密度曲线,但为了对比日间时段对占比的影响,希望在每个分面中叠加该Habitat下所有时段的合并占比数据的密度曲线。

当前代码:

Timeserod <- 
  plotsplit$erodius %>%
  group_by(Time) %>%
  ungroup()

etimesplits <- ggplot(data = Timeserod, aes(x = Proportion, col = Time)) +
  geom_density() +
  facet_wrap(~Habitat)
etimesplits

我曾考虑使用rbind函数,但不确定如何结合Habitat因子实现。以下是样本数据:

Number  Family  Time    Habitat Proportion
1   erodius Midday  Cardboard   0.32
2   erodius Midday  Cardboard   0.07
3   erodius Midday  Cardboard   0.27
4   erodius Midday  Cardboard   0.24
5   erodius Midday  Cardboard   0
6   erodius Midday  Cardboard   0.05
7   erodius Midday  Cardboard   0.46
8   erodius Midday  Cardboard   0.06
9   erodius Midday  Cardboard   0.23
10  erodius Midday  Cardboard   0.44
1   erodius Afternoon   Cardboard   0.17
2   erodius Afternoon   Cardboard   0.08
3   erodius Afternoon   Cardboard   0
4   erodius Afternoon   Cardboard   0
5   erodius Afternoon   Cardboard   0.14
6   erodius Afternoon   Cardboard   0.04
7   erodius Afternoon   Cardboard   0.68
8   erodius Afternoon   Cardboard   0.11
9   erodius Afternoon   Cardboard   0
10  erodius Afternoon   Cardboard   0.48
1   erodius Midday  Sand    0.23
2   erodius Midday  Sand    0
3   erodius Midday  Sand    0
4   erodius Midday  Sand    0.4
5   erodius Midday  Sand    0.01
6   erodius Midday  Sand    0.08
7   erodius Midday  Sand    0.15
8   erodius Midday  Sand    0.29
9   erodius Midday  Sand    0.15
10  erodius Midday  Sand    0.34
1   erodius Afternoon   Sand    0.03
2   erodius Afternoon   Sand    0.4
3   erodius Afternoon   Sand    0.8
4   erodius Afternoon   Sand    0.53
5   erodius Afternoon   Sand    0.54
6   erodius Afternoon   Sand    0.97
7   erodius Afternoon   Sand    0
8   erodius Afternoon   Sand    0.57
9   erodius Afternoon   Sand    0.56
10  erodius Afternoon   Sand    0.18
1   erodius Midday  Pine    0.24
2   erodius Midday  Pine    0.35
3   erodius Midday  Pine    0.97
4   erodius Midday  Pine    0.26
5   erodius Midday  Pine    0
6   erodius Midday  Pine    0.2
7   erodius Midday  Pine    0.08
8   erodius Midday  Pine    0.54
9   erodius Midday  Pine    0.27
10  erodius Midday  Pine    0.36
2   erodius Afternoon   Pine    0
3   erodius Afternoon   Pine    0
4   erodius Afternoon   Pine    0.03
5   erodius Afternoon   Pine    0
6   erodius Afternoon   Pine    0
7   erodius Afternoon   Pine    0.42
8   erodius Afternoon   Pine    0.08
9   erodius Afternoon   Pine    0.01
10  erodius Afternoon   Pine    0.28
1   erodius Midday  Soil    0
2   erodius Midday  Soil    0.65
3   erodius Midday  Soil    0
4   erodius Midday  Soil    0.23
5   erodius Midday  Soil    0
6   erodius Midday  Soil    0
7   erodius Midday  Soil    0
8   erodius Midday  Soil    0
9   erodius Midday  Soil    0.58
10  erodius Midday  Soil    0.02
1   erodius Afternoon   Soil    0
2   erodius Afternoon   Soil    0.03
3   erodius Afternoon   Soil    0.05
4   erodius Afternoon   Soil    0.44
5   erodius Afternoon   Soil    0
6   erodius Afternoon   Soil    0
7   erodius Afternoon   Soil    0
8   erodius Afternoon   Soil    0
9   erodius Afternoon   Soil    0.04
10  erodius Afternoon   Soil    0
解决方案

可以通过构造包含"合并时段"标记的数据集,再叠加一条不区分Time的密度曲线来实现,具体步骤如下:

  1. 准备合并数据:复制原数据集,将Time列统一标记为"Total",再和原数据合并,确保每个Habitat下都有对应合并时段的数据。
  2. 绘制叠加曲线:在原有ggplot代码基础上,新增一个geom_density层,专门调用合并后的数据,设置独特样式区分。

示例代码:

# 加载依赖包
library(dplyr)
library(ggplot2)

# 提取原始数据
original_data <- plotsplit$erodius

# 构造合并时段数据:复制原数据,将Time替换为"Total"
total_data <- original_data %>% mutate(Time = "Total")

# 合并原数据与总数据
combined_data <- bind_rows(original_data, total_data)

# 绘制密度图
etimesplits <- ggplot(data = combined_data, aes(x = Proportion, col = Time)) +
  geom_density(linewidth = 0.8) +
  # 单独设置Total曲线样式:黑色虚线,更突出
  geom_density(data = . %>% filter(Time == "Total"),
               aes(x = Proportion),
               col = "black",
               linetype = "dashed",
               linewidth = 1) +
  facet_wrap(~Habitat) +
  # 自定义分组颜色,让Total曲线更显眼
  scale_color_manual(values = c("Midday" = "blue", "Afternoon" = "red", "Total" = "black")) +
  labs(title = "甲虫停留时间占比密度图(按生境分面)",
       x = "停留时间占比",
       y = "密度",
       color = "日间时段") +
  theme_minimal()

etimesplits

代码说明:

  • bind_rows用于合并原数据和标记为"Total"的数据集,保证每个生境下都包含所有时段的合并数据。
  • 第二个geom_density层专门针对合并数据,用黑色虚线突出,便于和两个时段的曲线对比。
  • scale_color_manual自定义各分组颜色,避免Total曲线和其他时段颜色混淆。

这样每个分面中会同时显示Midday、Afternoon的密度曲线,以及该生境下所有时段合并后的密度曲线,满足对比需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:23:18