Live graph for app C

I have an application that periodically registers with the host system, it can be a file or just a console. I would like to use this data to build a statistical graph for me. I'm not sure if I can use a live graph for my application.

If this tool is correct, can I give an example of integrating an external application with live graphics?

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

+6
source share
2 answers

I think this is easiest to do with Python plus matplotlib . To achieve this, there are actually several ways: a) embed Python Interpreter directly in application C, b) print the data into standard output and transfer it to a simple Python script that actually performs graphing. Next, I will describe both approaches.

We have the following C application (e.g. plot.c ). It uses the Python interpreter to interact with matplotlib charting functions. An application can display data directly (when called as ./plot --plot-data ) and print data to stdout (when called with any other set of arguments).

 #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 this:

 $ ./plot --plot-data 

Then it will display red dots on the axis for a while.

When you decide not to output data directly, but print it to stdout , you can build using an external program (for example, a Python script called plot.py ) that receives data from stdin , that is, a channel, and displays the data that it gets. To do this, call a program like ./plot | python plot.py ./plot | python plot.py where plot.py is like:

 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 tested both approaches on my Debian machine. This requires the python2.7 and python-matplotlib .

EDIT

I just saw that you wanted to build a histogram or something similar, this, of course, is also possible using matplotlib, for example. bar chart:

 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() 
+6
source

Well, all you have to do is write down your data in this livegraph format and set up livegraph to plot what you want. If I wrote a small example C, which generates random numbers and resets them with time every second. Then you simply attach the livegraph program to the file. What is it.

When playing with LiveGraph, I have to say that its use is quite limited. I will still stick with the python script with matplotlib, since you have a lot more control over how and what is drawn.

 #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` 
+1
source

Source: https://habr.com/ru/post/902527/


All Articles