2011-11-28 4 views
6

Ho un'applicazione che registra periodicamente su un sistema host che potrebbe essere su un file o solo su una console. Mi piacerebbe usare questi dati per tracciare un grafico statistico per me. Non sono sicuro di poter utilizzare il grafico live per la mia applicazione.Grafico in tempo reale per un'applicazione C

Se questo strumento è quello giusto, posso avere un esempio sull'integrazione dell'applicazione esterna con il grafico live?

questo è collegamento livegraph ->http://www.live-graph.org/download.html

+0

Dov'è il collegamento allo strumento? – Hossein

+0

Che tipo di grafico statistico vuoi tracciare? LiveGraph sembra supportare solo i grafici a linee x/y, ma se scrivi nel file nel formato corretto dovrebbe essere in grado di mostrare il tuo grafico. – tinman

+0

Ho un file datalogger. il suo formato è .txt e ha numeri in una riga. (2,4 5,3 10,1 ecc.) voglio usare questo file in un programma che lo funziona – ozgur

risposta

1

Beh, avete solo bisogno di scrivere i dati in un determinato formato livegraph e impostare livegraph fino a tracciare ciò che si vuole. Se scritto un piccolo esempio in C che genera numeri casuali e li scarica insieme al tempo ogni secondo. Quindi, si collega il programma livegraph al file. Questo è tutto.

Giocare con LiveGraph devo dire che il suo uso è piuttosto limitato. Continuerò ad attenermi a uno script python con matplotlib, dal momento che hai molto più controllo su come e cosa viene tracciato.

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

compilare con

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

Penso che questo può essere realizzato più semplice utilizzando Python più matplotlib. Per ottenere questo ci sono in realtà diversi modi: a) integrare lo Python Interpreter direttamente nell'applicazione C, b) stampare i dati sullo stdout e collegarlo a un semplice script python che esegue il plotting. Di seguito descriverò entrambi gli approcci.

Abbiamo la seguente domanda C (ad esempio plot.c). Usa l'interprete Python per interfacciarsi con la funzionalità di tracciamento di matplotlib. L'applicazione è in grado di tracciare direttamente i dati (quando viene chiamato come ./plot --plot-data) e di stampare i dati su stdout (quando chiamato con qualsiasi altro argomento impostato).

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

Si può costruire in questo modo:

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

ed eseguirlo come:

$ ./plot --plot-data 

allora sarà eseguito per un certo tempo la stampa puntini rossi su un asse.

Quando si sceglie di non tracciare i dati direttamente, ma per stampare al stdout si può fare il tracciato da un programma esterno (ad esempio, uno script Python chiamato plot.py) che prende input da stdin, cioè un tubo, e le trame del dati che ottiene Per raggiungere questo obiettivo chiamare il programma come ./plot | python plot.py, con plot.py essere simile 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() 

ho provato entrambi gli approcci sulla mia macchina Debian. Richiede l'installazione dei pacchetti python2.7 e python-matplotlib.

EDIT

ho appena visto, che si voleva tracciare un grafico a barre o cosa del genere, questo naturalmente è possibile anche utilizzando matplotlib, per esempioun istogramma:

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()