LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Plotting realtime data with GNUPLOT (https://www.linuxquestions.org/questions/linux-software-2/plotting-realtime-data-with-gnuplot-911821/)

john_erlandsson 11-04-2011 06:39 AM

Plotting realtime data with GNUPLOT
 
Hi!

I am trying to write a C program to plot data from a bluetooth device.

GNUPLOT seemed to be the way to go.

So far i got:
Code:

set xrange [0:200]
set yrange [0:255]
set xtics 10
set ytics 10
set ylabel "Value"
set style data lines
set grid

plot \"-\" notitle
1
2
3
4
...and so on
e

The problem is that it doesn't plot the data on screen until it gets the terminating character 'e'.

Is there a way to get around this, and watch the data in real time?

//John

tronayne 11-04-2011 07:34 AM

Quote:

Originally Posted by john_erlandsson (Post 4515641)
Is there a way to get around this, and watch the data in real time?

Well, not really -- as with many things that monitor; e.g., top, ntop and others, you need to periodically refresh.

I had to do something similar once upon a once and I wound up gathering data for some period of time then spitting it out to GNUPLOT (with the execlp function I think, have a look at the manual page), killing that after a time and looping back to regenerate. Worked OK and most systems are fast enough nowadays that you don't really notice the "blink" when the old chart goes away and the new one pops up.

There might be some sort of Java thing you can do or a JavaScript thing to an HTML page but the GNUPLOT way isn't a bad idea either -- what works works, eh?

Hope this helps some.

jlinkels 11-04-2011 07:51 AM

It is fundamentally impossible to do that, because Gnuplot is a batch operation -- that is you first have to feed all the data before it can create a plot.

The solution would be to use not a single process loop, but a dual loop. Single means that you produce the data, and run Gnuplot immediately in the hope it will display the plot while data is produced. Dual loop means: one process collects the data and writes it to a file periodically. Then a second process picks up the data, and periodically creates the plot. This is not different as what tronayne wrote, it is just a more generic description.

Since you already seems to have your data acquisition process running, you have a number of choices for the Gnuplot loop: a bash script periodically calling display, or integrate it is a web page, where Gnuplot would produce the plot and Javascript refreshes it periodically. As a matter of fact this start to look like a triple loop.

If the plot is real simple you could consider using the Tk toolkit with Tcl or Python. Tk has some graph widgets.

jlinkels

john_erlandsson 11-04-2011 04:42 PM

Hi guys!

Thanks for taking an interest.

Just to make shure that I'm not confusing anyone by using the words realtime and plot, here is a snippet of my C application.

This function opens up a pipe to gnuplot and initiates the graph: (Basically stolen from the GNU Guile tutorial)
Code:

static FILE* start_gnuplot()
{
  FILE* output;
  int pipes[2];
  pid_t pid;

  pipe( pipes );
  pid = fork ();

  if ( !pid )
    {
      dup2( pipes[0], STDIN_FILENO );
      execlp( "gnuplot", NULL );
      return -1;
    }

  output = fdopen( pipes[1], "w" );

  fprintf (output, "set xrange [0:200]\n" );
  fprintf (output, "set yrange [0:255]\n" );
  fprintf (output, "set xtics 10\n");
  fprintf (output, "set ytics 10\n");
  fprintf (output, "set ylabel \"Value\"\n");
  fprintf (output, "set style data lines\n" );
  fprintf (output, "set grid\n" );
  fflush (output);

  return output;
}

The loop i use for testing looks like this: (It will be replaced by a loop that receives 8bits of data from a bluetooth socket and shipps that to gnuplot)
Code:

fprintf( global_output, "plot \"-\" notitle\n" );

int x;
  for( x = 0; x < 100; x++ )
  {
          fprintf( global_output, "%d\n", x );
          usleep( 30000 );
  }
  for( x = 100; x > 0; x-- )
  {
          fprintf( global_output, "%d\n", x );
          usleep( 30000 );
  }

fprintf( global_output, "e\n" ); //the gnuplot window doesn't open until it

I want to be able to log a continuous flow of data. It doesnt matter if i have to buffer a couple of sets before displaying them, as long as it appends to the curve instead of replacing it.

Does that make sense?


If this is not possible in gnuplot, I will probably do it in Qt...


All times are GMT -5. The time now is 03:43 PM.