如何标准化geom_density以展示不同量级x值的平滑直方图?
问题描述
我有一组包含两种不同量级测量值(height和width)的数据集,分别来自样本a和b。想用平滑直方图(geom_density)展示这两种测量值的变异性,不受绝对量级影响,但geom_density计算出的密度值量级差异极大。数据集代码如下:
library(tidyverse) set.seed(123) sample_a = tibble(sample = "a", height = rnorm(20, mean = 0.1, sd = 0.01), width = rnorm(20, mean = 50, sd = 10)) %>% pivot_longer(c(height, width), names_to = "parameter", values_to = "result") set.seed(321) sample_b = tibble(sample = "b", height = rnorm(20, mean = 0.2, sd = 0.03), width = rnorm(20, mean = 55, sd = 10)) %>% pivot_longer(c(height, width), names_to = "parameter", values_to = "result") data = bind_rows(sample_a, sample_b)
使用直方图时,以样本数量为y轴可比较各样本中目标参数的量级和变异性;但使用geom_density(即使加入y = after_stat(count))时,密度值的量级差异仍十分显著。请问如何用分面平滑直方图展示这些不同量级的测量结果?
解决方案
方法1:分面并设置自由坐标轴
通过分面将不同量级的参数分开展示,并设置自由坐标轴,让每个分面的y轴(或x+y轴)独立适配自身数据,避免量级差异干扰视觉对比。
代码示例:
# 同时放开x和y轴,适配每个参数的数值范围 ggplot(data, aes(x = result, fill = sample)) + geom_density(aes(y = after_stat(count)), alpha = 0.5) + facet_wrap(~parameter, scales = "free") + labs(x = "测量值", y = "样本数量")
如果只想放开y轴,保持x轴展示原始数值范围,可将scales = "free"改为scales = "free_y"。
方法2:对数据做标准化处理
针对每个参数的测量值做标准化转换(如Z-score),消除绝对量级差异,转换后的数据均值为0、标准差为1,可直接比较不同参数的相对变异性。
代码示例:
# 按parameter分组做标准化 data_normalized <- data %>% group_by(parameter) %>% mutate(result_norm = scale(result)) %>% ungroup() # 绘制标准化后的密度图 ggplot(data_normalized, aes(x = result_norm, fill = sample)) + geom_density(alpha = 0.5) + facet_wrap(~parameter) + labs(x = "标准化测量值", y = "概率密度")
方法3:使用概率密度(默认模式)
geom_density默认y轴为概率密度,曲线下面积为1,配合分面自由轴,可聚焦于分布形状的对比,忽略绝对数值的影响。
代码示例:
ggplot(data, aes(x = result, fill = sample)) + geom_density(alpha = 0.5, adjust = 1) + facet_wrap(~parameter, scales = "free") + labs(y = "概率密度")
内容的提问来源于stack exchange,提问作者aleoconn
相关产品推荐
相关产品推荐

