如何将R语言ks包生成的KDE家域列表对象转为可绘图对象?
问题描述
我有一个名为data的示例数据集,坐标如下(投影坐标系为CRS 5321):
longitude latitude 430547.6 7208993 404139.3 7212760 411915.5 7232663 430181.8 7239410 431756.6 7245202 436880.9 7267675 453830.3 7216400 465987.5 7210260 473772.0 7180114 478228.2 7182945
我尝试用R语言的ks包计算95% KDE家域,代码如下:
library(ks) h1 <- Hpi(data, pilot = "samse", binned = T) home.range <- kde(data, H = h1)
运行后得到一个列表类型的对象,我希望绘制该家域,但当前对象类型无法直接绘图,请问如何将其转换为可绘图对象(例如带x-y坐标的矩阵)?
解决方案
方法1:提取95%家域的轮廓坐标
ks包的kde对象包含密度估计的网格信息,可通过contourLines()提取指定置信水平的轮廓线,直接得到可绘图的坐标点:
# 提取95%置信水平对应的等高线(取密度值的5%分位数作为阈值) cl <- contourLines(x = home.range$eval.points[[1]], y = home.range$eval.points[[2]], z = home.range$estimate, levels = quantile(home.range$estimate, 0.05)) # 将轮廓线转换为数据框格式 cl_df <- do.call(rbind, lapply(cl, function(x) data.frame(long = x$x, lat = x$y)))
转换后的cl_df可直接用基础绘图或ggplot2绘制:
# 基础绘图:绘制家域边界+原始点 plot(cl_df$long, cl_df$lat, type = "l", main = "95% KDE家域") points(data, col = "red", pch = 16) # ggplot2绘图:填充家域区域+原始点 library(ggplot2) ggplot() + geom_polygon(data = cl_df, aes(x = long, y = lat), fill = "lightblue", alpha = 0.5) + geom_point(data = data, aes(x = longitude, y = latitude), color = "red") + theme_bw()
方法2:将KDE密度网格转换为数据框(适合热力图)
如果需要绘制密度热力图,可把kde对象的网格数据转换为长格式数据框:
# 生成包含所有网格坐标和对应密度值的数据框 grid_df <- expand.grid(long = home.range$eval.points[[1]], lat = home.range$eval.points[[2]]) grid_df$density <- as.vector(home.range$estimate) # 可选:筛选95%家域范围内的网格点 grid_df_95 <- grid_df[grid_df$density >= quantile(home.range$estimate, 0.05), ]
之后用ggplot2绘制热力图:
ggplot(grid_df, aes(x = long, y = lat, fill = density)) + geom_raster() + geom_contour(aes(z = density), breaks = quantile(home.range$estimate, 0.05), color = "red") + geom_point(data = data, aes(x = longitude, y = latitude), color = "white", size = 2) + scale_fill_viridis_c() + theme_bw()
方法3:直接使用ks包自带绘图函数
ks包本身提供了plot.kde()方法,可直接绘制kde对象,无需手动转换:
# 直接绘制KDE密度图,添加95%等高线 plot(home.range, cont = c(95), col = "lightblue") # 叠加原始数据点 points(data, col = "red", pch = 16)
内容的提问来源于stack exchange,提问作者Cam
相关产品推荐
相关产品推荐

