Gnuplot:如何仅重复y值的最后一次出现

时间:2018-04-19 12:25:29

标签: gnuplot

有没有办法不使用外部程序来避免在Gnuplot中的x位置绘制多个y值?

我研究过Gnuplot 5. *文档,发现只有一些不够接近的方法:例如smooth unique绘制所有y值的平均值smooth frequency绘制所有y值的 sum 。我只想采取最后一个值 - 类似的y值是"覆盖"。

我不想预处理数据,因为我需要在其数据块中保留记录,因为我需要在每个块之后绘制垂直线。

理想的解决方案是面向块的,即避免整个重复的块,但我也会感谢面向y的解决方案,它绘制了最后一次出现的唯一y值,而不管块是什么。

这是我最近的代码(重要部分):

stats ifname using 1 nooutput
columns = STATS_columns
blocks = STATS_blocks

ymax = -1e30
do for [i=2:columns] {
    stats ifname using i nooutput
    ymax = (ymax > valid(STATS_max)) ? ymax : STATS_max
}

plot for [j=2:columns] ifname using 1:j, \
  "" using 1:(column(0) == 1 ? ymax : NaN) axes x1y2 with impulse notitle lc black lw 0.75 dashtype 2

数据示例:

t sqr sqrt y 
4.000000    16.000000 2.000000 8.491226 
4.010000    16.080100 2.002498 8.576564 
4.055000    16.443025 2.013703 8.971325 
4.257500    18.126306 2.063371 10.985030 
4.510790    20.347226 2.123862 14.151540 
4.764080    22.696458 2.182677 18.230817 
5.000000    25.000000 2.236068 23.081549 


t sqr sqrt y 
5.000000    25.000000 2.236068 23.081549 
5.010000    25.100100 2.238303 23.313522 
5.055000    25.553025 2.248333 24.386594 
5.257500    27.641306 2.292924 29.860411 
5.508013    30.338210 2.346916 38.361213 
5.758527    33.160628 2.399693 49.282063 
6.000000    36.000000 2.449490 62.742164 


t sqr sqrt y 
5.000000    25.000000 2.236068 23.081549 
5.010000    25.100100 2.238303 23.083547 
5.055000    25.553025 2.248333 23.092489 
5.257500    27.641306 2.292924 23.131767 
6.000000    36.000000 2.449490 23.263871 


t sqr sqrt y 
6.000000    36.000000 2.449490 23.263871 
6.010000    36.120100 2.451530 23.497677 
6.055000    36.663025 2.460691 24.579225 
6.257500    39.156306 2.501500 30.096280 
6.508000    42.354068 2.551079 38.663729 
6.758501    45.677331 2.599712 49.670058 
7.000000    49.000000 2.645752 63.237766 

我想要实现的是完全忽略第二个块。到目前为止,结果如下: enter image description here

请注意,我希望y保持在sqr之下的示例只是特殊情况,所有功能都可以是独立的。

编辑:我在ewcz的脚本(columnhead)末尾添加了一些小的更改:

set y2range [0:ymax]

plot for [j=2:columns] for [b=0:blocks-1] ifname index b \
  using 1:(ignore[b+1] ? NaN : column(j)) lt (j-1) \
  title b==0 ? columnhead(j) : "", \
for [b=0:blocks-1] "" index b \
  using 1:(ignore[b+1] ? NaN : column(0) == 1 ? ymax : NaN) \
  axes x1y2 with impulse notitle \
  lc black lw 0.5 dashtype 2

1 个答案:

答案 0 :(得分:1)

根据自定义标准忽略某些块的临时解决方法可能如下(有关详细信息,请参阅代码中的注释):

set terminal pngcairo enhanced rounded
set output 'fig.png'

ifname = 'data.dat'

stats ifname using 1 nooutput
columns = STATS_columns
blocks = STATS_blocks

array signatures[blocks]
do for [j=0:blocks-1] {
  stats ifname index j:j using 1 nooutput

  #For each block, generate an identifier based on which we will decide if two
  #blocks are "duplicit" or not. In this particular case, consider the minimum
  #and maximum to 3 decimal digits. Due to the character of the technique used
  #below, this identifier should be a valid Gnuplot variable name.
  signatures[j+1] = sprintf("block_%d_%d", STATS_min*1000, STATS_max*1000)
}

#this array marks if a block should be ignored or not.
array ignore[blocks]

#Process blocks in reverse order and for each of them, check if the given
#signature has been already seen or not. If yes, it means that there is
#a more recent equivalent block in the data and the current block should
#be thus ignored. In order to check if a signature has been already seen,
#we set a corresponding variable and then test its existence via exists().
do for [j=blocks-1:0:-1] {
  signature = signatures[j+1]
  eval sprintf("ignore[%d] = exists(\"%s\");%s = 1;", j+1, signature, signature);
}

ymax = -1e30
do for [i=2:columns] {
    stats ifname using i nooutput
    ymax = (ymax > valid(STATS_max)) ? ymax : STATS_max
}

plot for [j=2:columns] for [b=0:blocks-1] ifname index b:b using 1:(ignore[b+1]?NaN:column(j)) w l lt (j-1) t b==0?sprintf('column %d', j):'', \
  "" using 1:(column(0) == 1 ? ymax : NaN) axes x1y2 with impulse notitle lc black lw 0.75 dashtype 2

这会产生: enter image description here