You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gnuplot中smooth kdensity的$kdensity1第二列含义及缩放常数求解

问题

刚接触Gnuplot,不熟悉其基于高斯的核密度重采样功能(smooth kdensity)。运行以下示例脚本后,想明确两个问题:

  1. 输出数据集$kdensity1第二列的计算逻辑是什么?
  2. 如何根据不同样本集确定合适的缩放常数?

附$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轴可视范围,要适配不同样本集,可按以下方式处理:

自动计算缩放系数

  1. 先统计$kdensity1第二列的最大值:
    stats $kdensity1 using 2 name 'KD'
    
    统计完成后,KD_max变量会存储第二列的峰值。
  2. 设定小提琴图的单侧最大宽度(比如希望在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:44:57