【问题标题】:GNUplot synchronizing piped raw data plot columnsGNUplot 同步管道原始数据绘图列
【发布时间】:2021-10-07 17:49:49
【问题描述】:

简述我的情况:

  1. 串行数据样本每秒数次到达大约 1K 字节大小

  2. c 程序 fopen'ed 到 tty - 预先添加 gnuplot 指令,订单传入 字节到数字和管道结果到 gnuplot

    c程序输出的简化示例


set terminal wxt noraise background rgb 'sea-green'
set autoscale
set title "Collected Data"
set yrange[-0.5:4.0]
set xrange[0:128]
plot "-" u (1.000000*$1):2 with lines lw 3 lc rgb 'dark-red', ""  u (1.000000*$1):3 with lines lw 3 lc rgb 'dark-blue'
 0.750  3.204  3.211
 1.750  0.150  0.139
 2.750  0.127  0.118
 3.750  0.109  0.098
 4.750  0.091  0.085
 5.750  0.081  0.074
e
  1. c 程序的输出通过管道传输到 gnuplot (./cprog | gnuplot)

gnuplot 窗口每秒用新数据更新几次,但是,这两个图表不是来自同一个数据样本。 这有点像每次只执行一个绘图命令。 所以,我正在寻找一种让我的跟踪同步的方法——最好的方法是什么? (希望保持更新率>1Hz)

【问题讨论】:

    标签: gnuplot


    【解决方案1】:

    您所展示的 plot 命令需要两个数据集才能完成。使用数据源"-" 的初始绘图组件从管道中读取一个数据集。第二个组件指定"",这意味着“使用与前一个绘图相同的数据源”。注意:相同的数据源,而不是相同的数据。所以它从管道中读取另一个数据集。

    以下命令序列应缓冲您的数据集之一,然后将其绘制两次。

    set table $temp
    plot "-" using (1.000000*$1):2:3 with table
    unset table
    plot $temp using 1:2 with lines, $temp using 1:3 with lines
    

    我想这会稍微降低你的最大重复率,但我并没有真正估计多少。它需要一个额外的格式化步骤来打印出临时表,但另一方面,管道中只有一个读取序列,而不是两个。

    【讨论】:

      【解决方案2】:

      谢谢伊桑! 这正是我希望存在的解决方案。

      所以这就是我想要的

      
      #! /usr/bin/gnuplot
      set terminal wxt persist noraise background rgb 'sea-green'
      set autoscale
      set title "Collected Data"
      set yrange[-0.5:4.0]
      set xrange[0:128]
      set table $temp
      plot "-" using 1:2:3 with table
       0.750  3.204  3.211
       1.750  0.150  2.539
       2.750  0.127  2.118
       3.750  0.109  1.598
       4.750  0.091  1.085
       5.750  0.081  0.574
      e
      unset table
      plot $temp u (1.000000*$1):2 with lines lw 3 lc rgb 'dark-red', $temp u (1.000000*$1):3 with lines lw 3 lc rgb 'dark-blue'
      

      今天早上我正要坐下来尝试定义三个数组并使用 gnuplot 命令 (array[x] = n) 而不是“-”数据转储来填充它们,然后绘制数组。这个解决方案让 gnuplot 通过在程序中添加三行来完成这项工作。

      您的解决方案显然是执行此任务的正确方法,感谢您这么快回复!

      【讨论】:

        【解决方案3】:

        假设我正确理解了您的问题,以下不是一个简单的解决方案吗?发送 2 个具有相同第一列的两列数据包。顺便问一下,你为什么用(1.000000*$1)?据我了解,gnuplot 已经将$1 解释为浮点数。

        代码:

        plot '-' u 1:2 with lines lw 3 lc rgb 'dark-red', '' u 1:2 with lines lw 3 lc rgb 'dark-blue'
         0.750  3.204
         1.750  0.150
         2.750  0.127
         3.750  0.109
         4.750  0.091
         5.750  0.081
        e
         0.750  3.211
         1.750  0.139
         2.750  0.118
         3.750  0.098
         4.750  0.085
         5.750  0.074
        e
        

        编辑:(在数据块中提供数据)

        #! /usr/bin/gnuplot
        set terminal wxt persist noraise background rgb 'sea-green'
        set autoscale
        set title "Collected Data"
        set yrange[-0.5:4.0]
        set xrange[0:128]
        $Data <<EOD
         0.750  3.204  3.211
         1.750  0.150  2.539
         2.750  0.127  2.118
         3.750  0.109  1.598
         4.750  0.091  1.085
         5.750  0.081  0.574
        EOD
        plot $Data u (1.000000*$1):2 with lines lw 3 lc rgb 'dark-red', '' u (1.000000*$1):3 with lines lw 3 lc rgb 'dark-blue'
        

        【讨论】:

        • 感谢您的回复,我相信您是对的,但 Ethan 的解决方案是我希望存在的解决方案。当我知道 gnuplot 应该能够做到这一点时,我真的不想在源代码或内联缓冲。
        • @baetis 如果可以在数据块中提供内联数据,为什么要先将其绘制到表格中?不确定是否存在性能差异。请参阅编辑后的答案。
        • 好的,这也可以。谢谢你。您认为 Ethan 的方法的执行时间是否相同?
        • @baetis 数据块只是提供数据。我假设绘制到表格涉及一些额外的过程。所以,我的猜测是数据块可能会更快。但可能可以忽略不计?!您需要比较这两种方法并进行一些时序测量。也许您甚至可以为此使用 gnuplot 的函数time(0.0),检查help time
        • @theoz:没有额外的处理。 set table $temp ... plot with table 创建一个数据块并用using 语句而不是绘图 的元素填充它。这是一种在线创建数据块的简单方法,并且具有执行using 规范中的任何算术处理的好处。
        【解决方案4】:

        感谢您对 gnuplot 中 datablock 工作原理的回复,这两个建议都很好地解决了我描述的问题。

        您的讨论让我想到了一种不同的解决方案,这种解决方案在某些情况下可能更快,并提供了将 gnuplot 用作循环缓冲区(存储最新的 n 值)的可能性,因此我只需要更新新的测量值。我会很感激任何 cmets。

        
        
        Is it true gnuplot stores array variables as memory indexed 64bit floating point?
            #! /usr/bin/gnuplot
            set terminal wxt persist noraise background rgb 'sea-green'
            set autoscale
            set title "Collected Data"
            set yrange[-0.5:4.0]
            array xa[100]
            array y1a[100]
            array y2a[100]
            xa[1] = 0.00; y1a[1] = 1.35; y2a[1] = 2.45
            xa[2] = 0.10; y1a[2] = 1.45; y2a[2] = 3.45
                   ....
            xa[50] = 4.90; y1a[1] = 1.55; y2a[1] = 1.45
            plot $temp u 2:(y1a[$1]) with lines lw 3 lc rgb 'dark-red', \
                 $temp u 2:(y2a[$1]) with lines lw 3 lc rgb 'dark-blue'
            
                   (then after a couple 100ms)
            xa[51] = 5.00; y1a[51] = 1.35; y2a[51] = 2.45
            xa[52] = 5.10; y1a[52] = 1.45; y2a[52] = 3.45
                   ....
            xa[100] = 9.90; y1a[100] = 1.55; y2a[100] = 1.45
            plot $temp u 2:(y1a[$1]) with lines lw 3 lc rgb 'dark-red', \
                 $temp u 2:(y2a[$1]) with lines lw 3 lc rgb 'dark-blue'
            
                   (then after a couple 100ms)
            xa[1] = 10.00; y1a[1] = 0.35; y2a[1] = 1.45
            xa[2] = 10.10; y1a[2] = 0.45; y2a[2] = 2.45
            plot $temp u 2:(y1a[$1]) with lines lw 3 lc rgb 'dark-red', \
                 $temp u 2:(y2a[$1]) with lines lw 3 lc rgb 'dark-blue'
            
                   (repeats every couple 100ms)
        
        

        gnuplot 将数组变量保存为内存索引的 64 位浮点是真的吗?

        【讨论】:

        • 在我看来,这将比之前的任何建议涉及更多的簿记开销。我希望它比简单地读取值表要慢,但我不太确定。另一方面,我也猜想任何速度瓶颈都在将绘图的矢量分量交给图形布局(qt/cairo/x11/...)的阶段,而不是值的内部簿记一旦他们被读入。
        • 既然你问,gnuplot数组作为结构数组存储在内存中;每个结构都包含一个保存 gnuplot 类型指示符的字段和一个保存类型值联合的字段。浮点数具有 gnuplot 类型 CMPLX,它的类型值相当于 C99(双复数)。
        猜你喜欢
        • 2014-01-07
        • 2013-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多