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

如何手动迭代x/y值并应用于gnuplot热力图解决重复数据问题?

解决Gnuplot热力图重复绘制的问题

你遇到的核心问题确实是同一(i,j)对被重复绘制了数百次,导致图像出现异常的“加粗”或颜色偏差。既然你已经成功计算出每个连接对的平均值数组Avg,我们可以直接基于这个数组生成热力图,完全跳过重复的原始数据。

关键解决方案:使用虚拟数据源++

Gnuplot的++可以生成一个覆盖你设定的x/y范围的网格数据集,每个整数坐标点仅出现一次,完美匹配你的(i,j)连接对需求。修改你的plot语句即可解决重复绘制的问题:

修改后的完整代码

# Color runs from white to green
set palette rgbformula -7,2,-7
set cblabel "Score"
unset cbtics
stats 'NxN_10GB.dat' using (column(10)) nooutput
set cbrange [STATS_min:STATS_max]
set output 'heatmap.png'
set title 'heatmap'
set xlabel 'en_id'
set ylabel 'pn_id'
set xrange [-1:10]
set yrange [-1:10]
set xtics 1
set ytics 1
# 确保热力图方块为正方形,填充更均匀
set size square
set style fill solid

# 获取en和pn的最大ID
stats 'NxN_10GB.dat' using (column(1)) nooutput
max_en = STATS_max
num_en = max_en + 1
stats 'NxN_10GB.dat' using (column(2)) nooutput
max_pn = STATS_max
num_pn = max_pn + 1
print sprintf("num_en = %d", num_en)
print sprintf("num_pn = %d", num_pn)

# 初始化平均值数组
array Avg[num_en * num_pn]
ind(a,b) = 1+a+b*num_pn  # gnuplot数组从1开始索引
getavg(a,b) = Avg[ind(a,b)]

# 填充平均值数组(保留原有逻辑)
do for [i=0:max_en] {
    do for [j=0:max_pn] {
        index = ind(i,j)
        stats 'NxN_10GB.dat' using ($1 == i && $2 == j && $3 == 10 ? column(10) : 1/0) nooutput
        Avg[index] = STATS_mean
        print sprintf("Avg[%2d,%2d] = %f",i,j,Avg[index])
    }
}

# 核心修改:用虚拟数据源++生成唯一的(i,j)点
plot ++ using 1:2:(getavg(int($1), int($2))) with image notitle, \
     ++ using 1:2:(sprintf("%.2f", getavg(int($1), int($2)))) with labels center notitle

关键修改点解释

  1. 替换原始数据源为++:
    ++会自动生成覆盖xrange和yrange的网格点,每个整数坐标仅出现一次,彻底避免了重复绘制同一连接对的问题。

    • int($1)和int($2)确保我们取整数坐标,匹配你的en_id和pn_id的整数类型。
  2. 优化图像显示:
    添加set size square确保热力图的方块是正方形,set style fill solid让颜色填充更均匀,消除不必要的空白。

  3. 标签格式化:
    把sprintf("%g")改成sprintf("%.2f")可以控制显示的小数位数,让标签更整洁易读。

额外优化建议

你当前嵌套循环调用stats的方式,每个(i,j)都要重新扫描一遍数据文件,当数据量很大时效率很低。可以改用Gnuplot的分组统计功能(需Gnuplot 5.2+),一次性完成所有分组的均值计算:

# 一次性按(en_id, pn_id)分组计算均值
stats 'NxN_10GB.dat' using 1:2:10 where ($3 == 10) by 1:2 nooutput prefix "CONN"

# 填充数组的逻辑简化为:
do for [i=0:max_en] {
    do for [j=0:max_pn] {
        Avg[ind(i,j)] = value(sprintf("CONN_mean_%d_%d", i, j))
    }
}

这种方法只需要扫描一次数据文件,速度会快很多,尤其适合你的大型数据文件场景。

验证效果

修改后,每个(i,j)连接对只会被绘制一次,热力图的方块会均匀显示,颜色也不会因为重复堆叠而出现异常。如果数据值本身接近,可以通过调整cbrange(比如缩小范围,或者用set palette maxcolors 20增加颜色梯度)来提升对比度,让差异更明显。

内容的提问来源于stack exchange,提问作者Andreas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:35:57