2011-11-28 21 views
6

Tengo una aplicación que se registra periódicamente en un sistema host que podría estar en un archivo o simplemente en una consola. Me gustaría utilizar estos datos para trazar un gráfico estadístico para mí. No estoy seguro si puedo usar el gráfico en vivo para mi aplicación.Gráfico en vivo para una aplicación C

Si esta herramienta es la correcta, ¿puedo darme un ejemplo al integrar la aplicación externa con el gráfico en vivo?

este es el enlace livegraph ->http://www.live-graph.org/download.html

+0

¿Dónde está el enlace a la herramienta? – Hossein

+0

¿Qué tipo de gráfico estadístico quiere trazar? LiveGraph parece solo admitir gráficos de líneas x/y, pero siempre que escriba en el archivo en el formato correcto, debería poder mostrar su gráfico. – tinman

+0

tengo un archivo de registro de datos. su formato es .txt y tiene números en una línea. (2,4 5,3 10,1 etc) quiero usar este archivo en un programa que funciona – ozgur

Respuesta

1

Bueno, sólo tiene que escribir sus datos en el formato dado de livegraph y establecer livegraph hasta trazar lo que quiere. Si escribió un pequeño ejemplo en C que genera números aleatorios y los va volcando junto con el tiempo cada segundo. A continuación, simplemente adjunte el programa livegraph al archivo. Eso es.

jugando con LiveGraph Debo decir que su uso es bastante limitado. Todavía me apegaría a un script de python con matplotlib, ya que tienes mucho más control sobre cómo y qué se traza.

#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; 
} 

compilar con

gcc -Wall main.c `gsl-config --cflags --libs` 
4

Creo que esto se puede lograr más fácil el uso de Python más matplotlib. Para lograr esto, existen varias maneras: a) integrar el Python Interpreter directamente en su aplicación C, b) imprimir los datos en stdout y conectarlos a una secuencia de comandos simple de python que hace el trazado real. A continuación, describiré ambos enfoques.

Tenemos la siguiente aplicación C (por ejemplo, plot.c). Utiliza el intérprete de Python para interactuar con la funcionalidad de trazado de matplotlib. La aplicación puede trazar los datos directamente (cuando se llama como ./plot --plot-data) e imprimir los datos a stdout (cuando se llama con cualquier otro conjunto de argumentos).

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

#define CMD_BUF_SIZE 256 

void initializePlotting() { 
    Py_Initialize(); 
    // load matplotlib for plotting 
    PyRun_SimpleString("from matplotlib import pyplot as pp"); 
    PyRun_SimpleString("pp.ion()"); // use pp.draw() instead of pp.show() 
} 

void uninitializePlotting() { 
    Py_Finalize(); 
} 

void plotPoint2d(double x, double y) { 
    // this buffer will be used later to handle the commands to python 
    static char command[CMD_BUF_SIZE]; 
    snprintf(command, CMD_BUF_SIZE, "pp.plot([%f],[%f],'r.')\npp.draw()", x, y); 
    PyRun_SimpleString(command); 
} 

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 < 1000; i++) { 
    double x = myRandom(), y = myRandom(); 
    if (plot) plotPoint2d(x,y); 
    else printf("%f %f\n", x, y); 
    } 

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

Se puede construir de esta manera:

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

y ejecutarlo como:

$ ./plot --plot-data 

A continuación se ejecutará durante algún tiempo el trazado de puntos rojos en un eje.

Cuando se opta por no representar los datos directamente, sino imprimir a la stdout puede hacer el trazado por un programa externo (por ejemplo, una secuencia de comandos de Python llamado plot.py) que toma la entrada de stdin, es decir, un tubo, y parcelas de la datos que obtiene Para lograr esta llamada, el programa como ./plot | python plot.py, con plot.py ser similar a:

from matplotlib import pyplot as pp 
pp.ion() 

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 
    pp.plot([x],[y],'r.') 
    pp.draw() 

He probado ambos enfoques en mi máquina Debian. Requiere que se instalen los paquetes python2.7 y python-matplotlib.

EDITAR

acabo de ver, que quería trazar un gráfico de barras o tal cosa, esto por supuesto es también posible matplotlib usando, por ejemplo,un histograma:

from matplotlib import pyplot as pp 
pp.ion() 

values = list() 
while True: 
    data = [float(x) for x in raw_input().split()] 
    values.append(data[0]) 
    pp.clf() 
    pp.hist([values]) 
    pp.draw() 
Cuestiones relacionadas