如何手动迭代图表的x和y值并将x,y索引应用于热图函数?

时间:2019-04-29 15:48:20

标签: gnuplot

我有一个很大的数据文件,其中包含许多快照 计算集群中相同节点的数量。 我正在测量每个连接的端点之间的数据速率,并希望在热图中显示结果。

但是,由于数据文件中有很多相同连接的快照,因此正常绘图将导致成千上万个数据点相互堆叠,这只会产生无法读取的图像-因此,我计划使用STATS来减少每个连接到3张图像的信息,信息的最小值,最大值,平均值。

我不知道如何正确使用plot函数来实现此目的,并且gnuplot的文档仅假设经过预处理的干净(非冗余矩阵)数据文件,这对我来说不是一个选择。

我已经设法为每个连接对(i,j)生成一个平均数据速率的数组,并将数据存储在avg [1 + i + j * max]中,它似乎可以完成我打算做的事情。

现在剩下要做的事情类似于

plot i:j:avg[1+i+j*max] with image

我当前的代码(如下所示)使用数据文件确定x,y值,然后将x,y的avg [...]用作z值。这导致许多具有相同值的堆叠图形,可以通过某些数据比其他数据更胖来识别它们,这可能是为什么我的图像效果不好的根本原因。因此,我试图将(x,y)分别从0迭代到n,并为每个(x,y)对绘制一次z值。

我不确定如何手动告诉plot命令,它将x和y分别从0迭代到n,然后使用avg [...]作为z值来绘制图像

当前的gnuplot已被剪掉

# 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

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
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
    print sprintf("index = %d",index)
    Avg[index] = STATS_mean
    print sprintf("Avg[%2d,%2d] = %f",i,j,Avg[index])
    }
}

plot 'NxN_10GB.dat' using 1:2:(Avg[1+$1+$2*num_pn]) with image , \
     'NxN_10GB.dat' using 1:2:(sprintf("%g",Avg[1+$1+$2*num_pn])) with labels

这是一个数据片段,大约有360个快照/连接对($ 1,$ 2)。我现在只对第1,2和10列感兴趣

en_id pn_id #en #pn time(sec) completions msg_size byte total_data(Gb) datarate(Gb/s)
0 0 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
0 1 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
0 2 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
0 3 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
0 4 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
0 5 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
0 6 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
0 7 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
0 8 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
0 9 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
1 0 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
1 1 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
1 2 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
1 3 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
1 4 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
1 5 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
1 6 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
1 7 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
1 8 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
1 9 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
2 0 10 10 10.0002 531 5048576 2680793856 21.4464 2.14459
2 1 10 10 10.0002 531 5048576 2680793856 21.4464 2.14459
2 2 10 10 10.0002 531 5048576 2680793856 21.4464 2.14459
3 3 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
3 4 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863
3 5 10 10 10.0002 532 5048576 2685842432 21.4867 2.14863

因此,标准的热图应使用color_code(value(i,j))为索引i,j的正方形着色。

所有测得的数据速率都非常接近(这实际上是一件好事),因此请不要惊讶,我们会看到相当无聊的统一图像:

set cbrange [0:STATS_max]

但是,如果我将颜色范围控制在非常接近平均结果的水平以获得更多的对比度,我会很惊讶地看到可怕的效果: set cbrange [STATS_min:STATS_max]

关于可能导致这种情况的原因,我有3种理论:

  1. 当前,我们绘制每个连接条目(但是具有相同的值)。因此,堆叠如此多的点可能会导致怪异的行为(我们可以在具有更多数据点的更多脂肪值下看到这一点)

  2. 由于某种原因正方形重叠

  3. cbrange太小,无法正确计算正确的颜色(但我对此表示怀疑)

关于1.这就是我要确认的问题。

编辑:

我预感产生了一些虚假数据,以降低其中一个节点上的平均数据速率。 但结果远非预期。我现在很困惑:( enter image description here

我们可以看到(1,1)平均下降到〜0.5,应该只是以更浅的绿色显示-但这是什么?!

edit2:

我提供了一些样本数据来查看我是否仍然神智健全。 每个(x,y)对的1个数据点会产生我一直在寻找的结果: enter image description here

所以解决我的问题肯定会回到原来的问题。

2 个答案:

答案 0 :(得分:1)

您可以使用++特殊文件名来创建(x,y)点的列表,然后可以使用该列表来索引数组。请参见help ++,以了解如何使用set urangeset samples等来设置这些点的间距。请记住,这些坐标是浮点数,因此,如果要将它们用作数组索引,则必须将它们舍入到最接近的整数。

类似的方法可能对您有用:

reset

set palette rgbformula -7,2,-7
1set 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 xtics 1
set ytics 1

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
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
    print sprintf("index = %d",index)
    Avg[index] = STATS_mean
    print sprintf("Avg[%2d,%2d] = %f",i,j,Avg[index])
    }
}

set urange [0:num_en-1]
set vrange[0:num_pn-1]
set samples num_en
set isosamples num_pn
plot "++" using 1:2:(Avg[1+int($1+0.5)+int($2+0.5)*num_pn]) w image, \
     "++" using 1:2:(sprintf("%g",Avg[1+int($1+0.5)+int($2+0.5)*num_pn])) with labels

答案 1 :(得分:0)

实现(我猜)您想要的东西的方式如下:

与其对过滤后的数据执行stats NxN次,而仅传递一次数据,您是否会通过提取最小值,最大值,总和和计数值并将它们放入数组来进行统计呢?如果您的连接之一没有数据,这种方法也可以容忍(请参见下图中的白色正方形)。

绘制为热图是一种方法。 您也可以使用with boxxyerror创建一个看起来“热图”的图。 绘制数据的另一个建议是绘制with yerrorbars并显示与平均值的偏差。这样一来,在同一图中可视化最小值和最大值也可能会更容易。

代码:

### statistics: minimum, maximum, average
reset session
set size square
set key left

FILE = "NxN_10GB.dat"  # skip random generation section and replace $Data with FILE

# generate some random data
M = 10
N = 10
set print $Data
do for [i=1:500] {
    print sprintf("%d %d 0 0 0 0 0 0 0 %g",int(rand(0)*N),int(rand(0)*M),rand(0)/100.+2.14)
}
set print

# get the size of the array
stats $Data u 1:2 nooutput
M = int(STATS_max_y+1)
N = int(STATS_max_x+1)
ConnectionsCount = M*N

# initialize arrays
array Min[ConnectionsCount]   
array Max[ConnectionsCount]   
array Sum[ConnectionsCount]
array Count[ConnectionsCount]
do for [i=1:ConnectionsCount] {
    Min[i] = NaN; Max[i] = NaN; Sum[i] = 0; Count[i] = 0
}

IndexNo(m,n) = m*N + n +1
set table $Dummy
    plot $Data u \
        (a=Min[IndexNo($1,$2)], Min[IndexNo($1,$2)] = ($10>=a && (a==a)) ? a : $10, \
         b=Max[IndexNo($1,$2)], Max[IndexNo($1,$2)] = ($10<=b && (b==b)) ? b : $10, \
         Sum[IndexNo($1,$2)] = Sum[IndexNo($1,$2)] + $10, \
         Count[IndexNo($1,$2)] = Count[IndexNo($1,$2)]+1 ) with table
unset table

set xrange[-0.5:N-0.5]
set xtics out
set yrange[-0.5:M-0.5]
set ytics out

SumTotal = sum[i=1:ConnectionsCount] (Sum[i])
CountTotal = sum[i=1:ConnectionsCount] (Count[i])
AverageTotal = SumTotal/CountTotal
print AverageTotal

set samples ConnectionsCount  # number of samples for '+'
set multiplot layout 2,1
    plot '+' u (int($0)%N):(int($0/N)):(0.5):(0.5):(Sum[$0+1]/Count[$0+1]) w boxxyerror lc palette fs solid 1.0 not

    set title sprintf("Deviation of average from total average %g",AverageTotal)    
    set size nosquare
    set xlabel "Number of connection"
    set xrange[0:ConnectionsCount+1]
    set yrange[*:*]
    plot '+' u ($0+1):(Sum[$0+1]/Count[$0+1]-AverageTotal):(Min[$0+1]-AverageTotal):(Max[$0+1]-AverageTotal) \
        with yerr pt 7 lc rgb "red" notitle
unset multiplot
### end of code

结果:

enter image description here