Gnuplot:如何使用重复的y值仅绘制最后一次出现的块

Gnuplot:如何使用重复的y值仅绘制最后一次出现的块,gnuplot,Gnuplot,有没有一种不使用外部程序的方法来避免在Gnuplot的x位置绘制多个y值 我研究了Gnuplot 5.*文档,只发现了一些不够接近的方法:例如smooth unique绘制所有y值的平均值,smooth frequency绘制所有y值的总和。我只想取最后一个值-类似的y值被“覆盖” 我不想预处理数据,因为我需要在数据块中保留记录,因为我需要在每个块后绘制垂直线 理想的解决方案是面向块的,即避免整个重复块,但我也很感激面向y的解决方案,它在最后一次出现时绘制唯一的y值,而不考虑块 以下是我最近的代

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

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

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

理想的解决方案是面向块的,即避免整个重复块,但我也很感激面向y的解决方案,它在最后一次出现时绘制唯一的y值,而不考虑块

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

数据示例:

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 
我想要实现的是完全忽略第二个块。以下是目前为止的结果:

请注意,我希望
y
保持在
sqr
下的示例只是一个特例,所有函数都可以是独立的

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


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

这将产生:

非常感谢,它工作得非常好。我想知道是否有数组结构,因为我没有在手册中找到它们。我在主线程中添加了一些小改动。@TomášKolárik,我的荣幸!自Gnuplot 5.1以来,
数组
构造就可用了,我相信。。。
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 
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
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