基于R绘制多物种分组观测的时序密度曲线
没问题,我来一步步帮你实现这个需求~
实现步骤
1. 准备数据与加载工具包
首先得把你的24小时观测数据导入R,我们会用到tidyverse这个全能工具包(包含数据处理的dplyr和绘图的ggplot2),如果还没安装的话先执行安装命令:
install.packages("tidyverse") library(tidyverse)
假设你的完整数据已经整理成数据框了,这里用你提供的示例数据做演示:
# 替换成你自己的完整24小时数据即可 obs_data <- data.frame( Hr = 1:5, Sp1 = c(8,3,5,7,5), Sp2 = c(25,14,25,26,19), Sp3 = c(1,0,1,1,0), Sp4 = c(7,50,4,4,7), Sp5 = c(7,4,10,11,11) )
2. 把数据转成适合绘图的格式
你的数据是宽格式(每个物种占一列),但ggplot2更擅长处理长格式数据(一列存物种名,一列存对应观测值),所以我们用pivot_longer做转换:
tidy_data <- obs_data %>% pivot_longer( cols = starts_with("Sp"), # 选中所有以Sp开头的列 names_to = "Species", # 把列名存到Species列 values_to = "Count" # 把对应的值存到Count列 )
转换后的数据会变成三列:小时(Hr)、物种(Species)、观测计数(Count),这样绘图时就能轻松区分不同物种了。
3. 绘制曲线(两种方案可选)
你提到的“密度曲线”,结合你的离散小时数据,我提供两种最贴合需求的方案:
方案一:折线+平滑趋势曲线(推荐)
这种方案既能展示每小时的真实观测值,又能呈现物种的整体变化趋势,最适合你的需求:
ggplot(tidy_data, aes(x = Hr, y = Count, color = Species)) + # 绘制各物种的折线,设置线条粗细和透明度 geom_line(size = 1, alpha = 0.7) + # 添加平滑趋势线,se=FALSE去掉置信区间,span调整平滑程度(越小越贴近原始数据) geom_smooth(se = FALSE, span = 0.3) + # 把x轴刻度改成你要的0100hr到2400hr格式 scale_x_continuous( breaks = 1:24, labels = str_pad(1:24, 2, pad = "0") %>% paste0("00hr") ) + # 设置图表标题和坐标轴标签 labs( x = "Time (24-hour period)", y = "Observation Count", title = "Hourly Observation Trends by Species" ) + # 用简洁的主题,把图例放在底部避免遮挡曲线 theme_minimal() + theme(legend.position = "bottom")
方案二:纯密度曲线(适合展示分布集中趋势)
如果你确实想展示观测值在时间上的密度分布(比如哪个时间段观测值更集中),可以用这个方案:
ggplot(tidy_data, aes(x = Hr, y = Count, color = Species)) + geom_density(stat = "identity", fill = NA, size = 1) + scale_x_continuous( breaks = 1:24, labels = str_pad(1:24, 2, pad = "0") %>% paste0("00hr") ) + labs( x = "Time (24-hour period)", y = "Density", title = "Hourly Observation Density by Species" ) + theme_minimal() + theme(legend.position = "bottom")
4. 自定义调整(可选)
如果想换曲线颜色、调整标题样式,比如自定义物种的颜色:
ggplot(tidy_data, aes(x = Hr, y = Count, color = Species)) + geom_line(size = 1, alpha = 0.7) + geom_smooth(se = FALSE, span = 0.3) + scale_x_continuous( breaks = 1:24, labels = str_pad(1:24, 2, pad = "0") %>% paste0("00hr") ) + # 自定义每个物种的曲线颜色 scale_color_manual( values = c("Sp1" = "red", "Sp2" = "blue", "Sp3" = "green", "Sp4" = "orange", "Sp5" = "purple") ) + labs( x = "Time (24-hour period)", y = "Observation Count", title = "Hourly Observation Trends by Species" ) + theme_minimal() + theme(legend.position = "bottom")
内容的提问来源于stack exchange,提问作者S.Roy
相关产品推荐
相关产品推荐

