如何用R包绘制逐年核密度图?复刻指定文献可视化样式
需求与问题
我统计了每年论文摘要和标题中感叹号的出现次数,希望通过**核密度估计(Kernel Density Estimation)**展示每年该次数的分布,目标是复刻Plavén-Sigray等人2017年发表于eLife的文献中的可视化样式。我尝试用ggplot2绘制,但输出结果不符合预期,附上测试用示例代码,请求推荐合适的R包及实现方法。
测试代码
library(ggplot2) set.seed(176) df = data.frame( id = seq(1:2000), amount = sample(0:3, 2000, replace = TRUE), year = sample(1990:2010, 2000, replace = T) ) ggplot(df, aes(x = year, y = amount) ) + geom_density_2d() + geom_density_2d_filled() + geom_density_2d(colour = "black")
解决方案
要复刻目标可视化样式,核心是展示每个年份内感叹号次数的单变量核密度分布——你之前的代码用了geom_density_2d,这是计算年份与次数的二维联合密度,和需求偏差是问题根源。以下是两种高效实现方式:
方法1:用ggridges绘制脊线密度图(最贴近目标样式)
ggridges专门用于展示分组变量的分布趋势,能直观呈现各年份感叹号次数的密度变化:
library(ggplot2) library(ggridges) set.seed(176) df = data.frame( id = seq(1:2000), amount = sample(0:3, 2000, replace = TRUE), year = factor(sample(1990:2010, 2000, replace = T)) # 将年份转为因子用于分组 ) ggplot(df, aes(x = amount, y = year, fill = stat(density))) + geom_density_ridges_gradient(scale = 3, rel_min_height = 0.01) + scale_fill_viridis_c(name = "密度") + labs(x = "感叹号出现次数", y = "年份") + theme_minimal()
方法2:用基础ggplot2分面展示单变量密度
如果更倾向于原生ggplot2,可以按年份分面绘制密度曲线,清晰对比每年分布:
library(ggplot2) set.seed(176) df = data.frame( id = seq(1:2000), amount = sample(0:3, 2000, replace = TRUE), year = sample(1990:2010, 2000, replace = T) ) ggplot(df, aes(x = amount, fill = factor(year))) + geom_density(alpha = 0.6) + facet_wrap(~year, ncol = 5) + labs(x = "感叹号出现次数", y = "密度") + theme_bw() + theme(legend.position = "none") # 分面下无需重复图例
关键调整说明
目标可视化的核心是聚焦「单年份内的次数分布」,而非年份和次数的联合分布,所以必须切换为按年份分组的单变量核密度估计,以上两种方法都能精准匹配这个需求。
内容的提问来源于stack exchange,提问作者Irazall
相关产品推荐
相关产品推荐

