gnuplot中smooth freq无法生成分组数据直方图的问题求助
Gnuplot分组直方图
smooth freq失效问题解决 问题描述
尝试在单张图表中创建三个分组直方图,数据筛选功能正常,但使用smooth freq命令未达到预期效果。数据集包含三个分组(Med=2、3、4),通过自定义函数筛选各分组的年龄值,最终生成的图表仅显示每个数据点的单个尖峰(颜色区分正确)。
原始数据集
$Data <<EOD Med Gender Age 4 f 33.14 4 f 53.81 4 f 32.99 4 m 39.78 4 f 25.06 2 m 51.06 4 f 39.93 4 f 44.92 2 m 45.68 2 m 73.47 2 m 61.65 4 m 26.82 4 f 24.93 4 f 29.79 3 m 80.54 3 m 81.42 2 f 71.9 2 f 73.18 3 m 64.76 4 m 33.45 2 m 58.92 2 f 73.51 4 f 36.09 EOD
原始代码
GROUP_LABELS = "2 3 4" GROUP_NAMES = "Med_02 Med_03 Med_04" is_true(c,x) = ( c == x ) ? 1.0 : NaN age = "( column(\"Age\") )" selected_age_values = "is_true( column(\"Med\"), i ) * @age" x_min = 0 x_max = 100 n_bins = 20 bin_width = 1.*(x_max - x_min)/n_bins bin(col) = floor(column(col)/bin_width)*bin_width set boxwidth 0.5 set xtics out set xrange[x_min:x_max] plot for [i in GROUP_LABELS] $Data u ( @selected_age_values ):(1) smooth freq w boxes lc i-1 ti word( GROUP_NAMES, i-1 ) noenhanced
问题原因
当前代码的核心问题是未对数据做分箱预处理:
smooth freq会直接统计每个原始Age值的出现次数,而非按区间分组统计- 每个原始年龄值基本唯一,因此每个点只会生成高度为1的尖峰,无法形成连续的直方图区间
修正方案
关键修改点
- 先分箱再统计:对筛选后的年龄值计算对应的分箱起始值,让
smooth freq统计每个区间的点数 - 调整箱宽:将
boxwidth设置为分箱宽度的合理比例(比如0.8),避免箱子重叠或间距过大 - 简化变量引用:去掉字符串宏
@age和@selected_age_values,直接在plot命令中计算,减少潜在错误
修正后代码
GROUP_LABELS = "2 3 4" GROUP_NAMES = "Med_02 Med_03 Med_04" x_min = 0 x_max = 100 n_bins = 20 bin_width = 1.*(x_max - x_min)/n_bins # 分箱函数:计算年龄对应的箱起始值 bin(age) = floor(age/bin_width)*bin_width set boxwidth bin_width * 0.8 # 箱宽设为分箱宽度的80%,避免重叠 set xtics out set xrange[x_min:x_max] set ylabel "Count" set title "Age Distribution by Med Group" # 循环绘制每个分组:先筛选Med=i的数据,再分箱,最后用smooth freq统计计数 plot for [i in GROUP_LABELS] $Data u (column("Med") == i ? bin(column("Age")) : NaN):(1) \ smooth freq w boxes lc i-1 ti word(GROUP_NAMES, i-1) noenhanced
效果说明
修正后的代码会:
- 对每个分组的年龄数据按指定区间分箱
smooth freq统计每个分箱内的数据点数量,生成正常的直方图柱子- 箱宽适配分箱区间,确保图表展示清晰的分组分布
内容的提问来源于stack exchange,提问作者magfan
相关产品推荐
相关产品推荐

