Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Live graph for a C application

I have an application which logs periodically on to a host system it could be on a file or just a console. I would like to use this data to plot a statistical graph for me. I am not sure if I can use the live graph for my application.

If this tool is the right one, may I have an example on integrating the external application with the live graph?

this is livegraph link --> http://www.live-graph.org/download.html

like image 387
14 revs, 3 users 99% Avatar asked Nov 28 '11 09:11

14 revs, 3 users 99%


People also ask

What graph should I use for temperature?

Temperature is always shown in the form of a line graph.

What is a live graph?

LiveGraph is a framework for real-time data visualisation, analysis and logging. Distinctive features: A real-time plotter that can automatically update graphs of your data while it is still being computed by your application.

How do you plot real-time data?

To create a real-time plot, we need to use the animation module in matplotlib. We set up the figure and axes in the usual way, but we draw directly to the axes, ax , when we want to create a new frame in the animation.

Which application software is most suitable for a chart or graph?

1. Visme. Visme is the best software for graphs and charts thanks to the immense integrated capabilities. Its ease and versatility make it a real professional designer tool.


2 Answers

I think this can be achieved easiest using Python plus matplotlib. To achieve this there are actually multiple ways: a) integrating the Python Interpreter directly in your C application, b) printing the data to stdout and piping this to a simple python script that does the actual plotting. In the following I will describe both approaches.

We have the following C application (e.g. plot.c). It uses the Python interpreter to interface with matplotlib's plotting functionality. The application is able to plot the data directly (when called like ./plot --plot-data) and to print the data to stdout (when called with any other argument set).

#include <Python.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

void initializePlotting() {
  Py_Initialize();
  // load matplotlib for plotting
  PyRun_SimpleString(
    "from matplotlib import pyplot as plt\n"
    "plt.ion()\n"
    "plt.show(block=False)\n"
    );
}

void uninitializePlotting() {
  PyRun_SimpleString("plt.ioff()\nplt.show()");
  Py_Finalize();
}

void plotPoint2d(double x, double y) {
#define CMD_BUF_SIZE 256
  static char command[CMD_BUF_SIZE];
  snprintf(command, CMD_BUF_SIZE, "plt.plot([%f],[%f],'r.')", x, y);
  PyRun_SimpleString(command);
  PyRun_SimpleString("plt.gcf().canvas.flush_events()");
}

double myRandom() {
  double sum = .0;
  int count = 1e4;
  int i;
  for (i = 0; i < count; i++)
    sum = sum + rand()/(double)RAND_MAX;
  sum = sum/count;
  return sum;
}

int main (int argc, const char** argv) {
  bool plot = false;
  if (argc == 2 && strcmp(argv[1], "--plot-data") == 0)
    plot = true;

  if (plot) initializePlotting();

  // generate and plot the data
  int i = 0;
  for (i = 0; i < 100; i++) {
    double x = myRandom(), y = myRandom();
    if (plot) plotPoint2d(x,y);
    else printf("%f %f\n", x, y);
  }

  if (plot) uninitializePlotting();
  return 0;
}

You can build it like this:

$ gcc plot.c -I /usr/include/python2.7 -l python2.7 -o plot

And run it like:

$ ./plot --plot-data

Then it will run for some time plotting red dots onto an axis.

When you choose not to plot the data directly but to print it to the stdout you may do the plotting by an external program (e.g. a Python script named plot.py) that takes input from stdin, i.e. a pipe, and plots the data it gets. To achieve this call the program like ./plot | python plot.py, with plot.py being similar to:

from matplotlib import pyplot as plt
plt.ion()
plt.show(block=False)
while True:
  # read 2d data point from stdin
  data = [float(x) for x in raw_input().split()]
  assert len(data) == 2, "can only plot 2d data!"
  x,y = data
  # plot the data
  plt.plot([x],[y],'r.')
  plt.gcf().canvas.flush_events()

I have tested both approaches on my debian machine. It requires the packages python2.7 and python-matplotlib to be installed.

EDIT

I have just seen, that you wanted to plot a bar plot or such thing, this of course is also possible using matplotlib, e.g. a histogram:

from matplotlib import pyplot as plt
plt.ion()
plt.show(block=False)
values = list()
while True:
  data = [float(x) for x in raw_input().split()]
  values.append(data[0])
  plt.clf()
  plt.hist([values])
  plt.gcf().canvas.flush_events()
like image 163
moooeeeep Avatar answered Nov 09 '22 05:11

moooeeeep


Well, you only need to write your data in the given format of livegraph and set livegraph up to plot what you want. If wrote small C example which generates random numbers and dumps them together with the time every second. Next, you just attach the livegraph program to the file. That's it.

Playing around with LiveGraph I must say that its use is rather limited. I still would stick to a python script with matplotlib, since you have much more control over how and what is plotted.

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>

int main(int argc, char** argv)
{
        FILE *f; 
        gsl_rng *r = NULL;
        const gsl_rng_type *T; 
        int seed = 31456;   
        double rndnum;
        T = gsl_rng_ranlxs2;
        r = gsl_rng_alloc(T);
        gsl_rng_set(r, seed);

        time_t t;
        t = time(NULL);



        f = fopen("test.lgdat", "a");
        fprintf(f, "##;##\n");
        fprintf(f,"@LiveGraph test file.\n");
        fprintf(f,"Time;Dataset number\n");

        for(;;){
                rndnum = gsl_ran_gaussian(r, 1); 
                fprintf(f,"%f;%f\n", (double)t, rndnum);
                sleep(1);
                fflush(f);
                t = time(NULL);
        }   

        gsl_rng_free(r);
        return 0;
}

compile with

gcc -Wall main.c  `gsl-config --cflags --libs`
like image 32
Bort Avatar answered Nov 09 '22 04:11

Bort