Gnuplot中smooth kdensity的$kdensity1第二列含义及缩放常数求解
问题
刚接触Gnuplot,不熟悉其基于高斯的核密度重采样功能(smooth kdensity)。运行以下示例脚本后,想明确两个问题:
- 输出数据集
$kdensity1第二列的计算逻辑是什么? - 如何根据不同样本集确定合适的缩放常数?
附$kdensity1部分输出数据:
(...) 140.76 13.1663 13.1663 i 146.032 12.5092 12.5092 i 151.304 11.6501 11.6501 i 156.575 10.6298 10.6298 i 161.847 9.5347 9.5347 i 167.119 8.48325 8.48325 i 172.391 7.56657 7.56657 i 177.662 6.80631 6.80631 i (...)
示例脚本:
nsamp = 3000 set print $viol1 do for [i=1:nsamp] { y = (i%4 == 0) ? 300. + 70.*invnorm(rand(0)) \ : (i%4 == 1) ? 400. + 10.*invnorm(rand(0)) \ : 120. + 40.*invnorm(rand(0)) print sprintf(" 35.0 %8.5g", y) } unset print set title "kdensity mirrored sideways to give a violin plot" set table $kdensity1 plot $viol1 using 2:(1) smooth kdensity bandwidth 10. with filledcurves above y lt 9 title 'B' unset table set border 2 unset margins unset xtics set ytics nomirror rangelimited set xrange [-1:5] plot $kdensity1 using (3 + $2/20.):1 with filledcurve x=3 lt 9 notitle, '' using (3 - $2/20.):1 with filledcurve x=3 lt 9 notitle
解答
1. $kdensity1第二列的计算逻辑
smooth kdensity实现的是高斯核密度估计(KDE),$kdensity1各列的含义:
- 第1列:核密度估计的采样点,对应输入样本的取值(即
$viol1的第二列数据) - 第2列:该采样点的核密度累加值,计算逻辑为:
对每个样本点,用指定带宽的高斯核函数计算其在当前采样点位置的贡献,然后将所有样本的贡献相加。这个数值和样本总量、带宽直接相关——样本越多、带宽越小,该值的峰值越高。
公式近似为:$\sum_{i=1}^n K\left(\frac{x - x_i}{h}\right)$,其中$K$是高斯核函数,$h$是设定的带宽,$n$是样本总数(未做归一化,因此数值与样本量正相关)。
2. 确定合适的缩放常数
脚本中$2/20.0是为了将密度值缩放到x轴可视范围,要适配不同样本集,可按以下方式处理:
自动计算缩放系数
- 先统计
$kdensity1第二列的最大值:
统计完成后,stats $kdensity1 using 2 name 'KD'KD_max变量会存储第二列的峰值。 - 设定小提琴图的单侧最大宽度(比如希望在x=3左右各延伸2个单位),则缩放系数为
KD_max / 目标单侧宽度,绘图时用$2 / 缩放系数即可让密度值刚好填满目标宽度。示例代码:target_side_width = 2 # 单侧宽度 scale = KD_max / target_side_width plot $kdensity1 using (3 + $2/scale):1 with filledcurve x=3 lt 9 notitle, \ '' using (3 - $2/scale):1 with filledcurve x=3 lt 9 notitle
动态适配x轴范围
如果不想固定宽度,可根据密度峰值动态调整xrange:
scale_factor = 0.05 # 控制宽度的比例系数,可按需调整 set xrange [3 - scale_factor*KD_max : 3 + scale_factor*KD_max] plot $kdensity1 using (3 + $2*scale_factor):1 with filledcurve x=3 lt 9 notitle, \ '' using (3 - $2*scale_factor):1 with filledcurve x=3 lt 9 notitle
若是多组小提琴图对比,取所有组密度峰值的最大值作为统一缩放基准,可保证各组宽度一致。
内容的提问来源于stack exchange,提问作者Guy B
相关产品推荐
相关产品推荐

