0

My situation briefly described :

  1. serial data samples are arriving about a 1K byte size several times per second

  2. c program fopen'ed to tty - prepends gnuplot instructions, orders incoming bytes to numbers and pipes results into gnuplot

    Simplified example of c program output


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. the output of the c program is piped into gnuplot (./cprog | gnuplot)

The gnuplot window updates with new data several times per second, BUT, the two graphs are not from the same data sample. It's sorta like each time through only one of the plot commands is executed. So, I'm looking for a way to get my traces synced - what's the best way to do this? (Hoping to keep update rate >1Hz)

4 Answers 4

1

The plot command as you have shown it requires two data sets to complete. The initial plot component using data source "-" reads one data set from the pipe. The second component specifies "" which means "use the same data source as the previous plot". Note: same data source, not same data. So it reads another data set from the pipe.

The following command sequence should buffer one of your data sets and then plot it twice.

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

I imagine that will slow down your maximum repetition rate slightly, but I don't really have an estimate for how much. It requires an extra formatting step to print out the temporary table, but on the other hand there is only one read sequence from the pipe rather than two.

Sign up to request clarification or add additional context in comments.

Comments

0

Thank you Ethan! This was exactly the solution I hoped existed.

So this does what I wanted


#! /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'

I was just about to sit down this morning and try defining three arrays and populating them using gnuplot commands (array[x] = n) instead of '-' data dump, and then plot the arrays. This solution has gnuplot do the work by adding three lines to program.

Your solution is clearly the right way to perform this task, thanks for getting back so quickly!

Comments

0

Assuming I understood your question correctly, wouldn't the following be a simple solution? Send 2 two-column data packages having the identical first column. By the way, why are you using (1.000000*$1)? As I understand, gnuplot will already interpret $1 as floating point number.

Code:

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

Edit: (provide data in a datablock)

#! /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'

5 Comments

Thank you for response, I believe you are right, but Ethan's solution was solution that I hoped existed. I really didn't want to do buffering at source or inline when I just knew that gnuplot should be able to do it.
@baetis why do you want to plot it to a table first if you can provide the data inline in a datablock? Not sure whether there is a performance difference. See edited answer.
Okay this works too. Thank you. Would Ethan's method be about the same execution time do you think?
@baetis the datablock simply provides data. I assume plotting to a table involves some extra processes. So, my guess would be that a datablock might be faster. But probably negligible?! You need to compare the two approaches and do some timing measurements. Maybe you could even use gnuplot's function time(0.0) for this, check help time.
@theoz: No extra processing. set table $temp ... plot with table creates a datablock and fills it with the elements of the using statement <i>instead of plotting</i>. It's a simple way to create a datablock in-line and has the benefit of executing any arithmetic processing in the using spec as it goes.
0

Thank you the responses on the workings of datablock in gnuplot, both of the recommendations solved the problem that I described excellently.

Your discussion got me thinking about a different solution that may be faster under some circumstances and offers the possibility of using gnuplot as a circular buffer (storing latest n values) so that I only need update new measurements. I would appreciate any comments.



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)

Is it true gnuplot saves array variables as memory indexed 64 bit floating point?

2 Comments

To my eye that would involve a lot more bookkeeping overhead than any of the previous suggestions. I would expect it to be slower than simply reading a table of values but I'm not really sure. On the other hand, I would also guess that any speed bottleneck is at the stage of handing of the vector components of the plot to the graphics layout (qt/cairo/x11/...), not the internal bookkeeping of values once they are read in.
Since you ask, gnuplot arrays are stored in memory as an array of structures; each structure contains a field holding a gnuplot type indicator and field holding a union of typed values. A floating point number has gnuplot type CMPLX and it's typed value is equivalent to C99 (double complex).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.