如何在R的ggplot中仅绘制stat_density_2d/geom_density_2d的顶层等高线
解决方案
一、仅保留stat_density_2d的前4个高层级(填充多边形)
直接在stat_density_2d中通过after_stat()筛选密度最高的4个层级即可:
library(ggplot2) df <- data.frame(x=rnorm(2000, 10, 3), y=rnorm(2000, 10, 3)) stat_density_plot <- ggplot(df, aes(x, y)) + geom_point(alpha = 0.3) + # 降低点透明度,避免遮挡等高线 stat_density_2d(aes(fill = after_stat(level)), geom = "polygon", bins = 15, data = ~ filter(.x, after_stat(level) %in% tail(sort(unique(after_stat(level))), 4))) stat_density_plot
核心逻辑:先对所有层级排序,取最后4个(即最高的4个层级),仅保留这些层级对应的多边形。
二、仅保留geom_density_2d的最内侧4条等高线
最内侧等高线对应最高密度层级,同样用after_stat()筛选目标层级:
geom_density_plot <- ggplot(df, aes(x, y)) + geom_point(alpha = 0.3) + geom_density_2d(bins = 15, color = "red", data = ~ filter(.x, after_stat(level) %in% tail(sort(unique(after_stat(level))), 4))) geom_density_plot
三、手动用MASS::kde2d计算密度后绘制
如果需要基于手动生成的核密度估计绘图,可将结果整理为数据框后用geom_contour_filled/geom_contour实现:
library(MASS) library(dplyr) library(tidyr) # 计算核密度 kde <- kde2d(df$x, df$y, n = 100, h = c(3,3)) # 转换为ggplot兼容的长格式数据框 kdf <- data.frame( x = rep(kde$x, each = length(kde$y)), y = rep(kde$y, length(kde$x)), z = as.vector(kde$z) ) # 提取最高的4个层级阈值(对应bins=15的层级划分逻辑) levels <- quantile(kdf$z, seq(0, 1, length.out = 16)) top4_levels <- tail(levels, 4) # 绘制填充多边形 manual_stat_plot <- ggplot(kdf, aes(x, y)) + geom_point(data = df, alpha = 0.3) + geom_contour_filled(aes(z = z), breaks = top4_levels) # 绘制等高线 manual_geom_plot <- ggplot(kdf, aes(x, y)) + geom_point(data = df, alpha = 0.3) + geom_contour(aes(z = z), breaks = top4_levels, color = "red")
内容的提问来源于stack exchange,提问作者Andrea
相关产品推荐
相关产品推荐

