2010-08-19 12 views
16

J'ai écrit un programme qui écrit une liste de données dans un fichier '.dat' avec l'intention de le tracer séparément en utilisant gnuplot. Y a-t-il un moyen de rendre mon code automatiquement? Ma sortie est de la forme:Création d'un graphe de code C automatiquement un graphique

x-coord analytic approximation 
x-coord analytic approximation 
x-coord analytic approximation 
x-coord analytic approximation 
x-coord analytic approximation 
.... 

Idéalement, quand je lance le code graphique serait également imprimé avec un x-label, label y et le titre (ce qui pourrait être changé de mon code C). Merci beaucoup.

+1

Peut-être vérifier la fonction 'installation privée. – sje397

Répondre

32

Je suis tombé sur ce tout en recherchant quelque chose d'autre concernant gnuplot. Même si c'est une vieille question, je pensais que je contribuerais un exemple de code. J'utilise ceci pour un de mes programmes, et je pense que c'est un travail assez ordonné. AFAIK, ce PIPE ne fonctionne que sur les systèmes Unix (voir la modification ci-dessous pour les utilisateurs de Windows). Mon installation gnuplot est l'installation par défaut du référentiel Ubuntu.

#include <stdlib.h> 
#include <stdio.h> 
#define NUM_POINTS 5 
#define NUM_COMMANDS 2 

int main() 
{ 
    char * commandsForGnuplot[] = {"set title \"TITLEEEEE\"", "plot 'data.temp'"}; 
    double xvals[NUM_POINTS] = {1.0, 2.0, 3.0, 4.0, 5.0}; 
    double yvals[NUM_POINTS] = {5.0 ,3.0, 1.0, 3.0, 5.0}; 
    FILE * temp = fopen("data.temp", "w"); 
    /*Opens an interface that one can use to send commands as if they were typing into the 
    *  gnuplot command line. "The -persistent" keeps the plot open even after your 
    *  C program terminates. 
    */ 
    FILE * gnuplotPipe = popen ("gnuplot -persistent", "w"); 
    int i; 
    for (i=0; i < NUM_POINTS; i++) 
    { 
    fprintf(temp, "%lf %lf \n", xvals[i], yvals[i]); //Write the data to a temporary file 
    } 

    for (i=0; i < NUM_COMMANDS; i++) 
    { 
    fprintf(gnuplotPipe, "%s \n", commandsForGnuplot[i]); //Send commands to gnuplot one by one. 
    } 
    return 0; 
} 

EDIT

Dans ma demande, j'ai aussi couru dans le problème que l'intrigue ne semble pas que le programme d'appel est fermé. Pour contourner cela, ajoutez un fflush(gnuplotPipe) après avoir utilisé fprintf pour lui envoyer votre dernière commande.

J'ai également vu que les utilisateurs de Windows peuvent utiliser _popen à la place de popen - mais je ne peux pas le confirmer car je n'ai pas installé Windows.

EDIT 2

On peut éviter d'avoir à écrire dans un fichier en envoyant la commande gnuplot plot '-' suivi par des points de données, suivi de la lettre « e ».

par exemple.

fprintf(gnuplotPipe, "plot '-' \n"); 
int i; 

for (int i = 0; i < NUM_POINTS; i++) 
{ 
    fprintf(gnuplotPipe, "%lf %lf\n", xvals[i], yvals[i]); 
} 

fprintf(gnuplotPipe, "e"); 
+0

Je sais que cela a été très long depuis que cette réponse a été publiée, mais j'ai utilisé le code de votre seconde édition plus la boucle for avec le 'commandsForGnuplot' dedans pour ajouter des commandes , et il trace mais il n'ajoute aucune des commandes (title, xlabel ou ylabel) .Comment puis-je les ajouter sinon comme ça? –

5

Vous pouvez créer un script gnuplot et générer un processus exécutant gnuplot pour tracer ce script à partir de la ligne de commande, ou vous pouvez utiliser l'une des interfaces fournies. C, il existe une interface pipe POSIX de Nicolas Devillard ici: http://ndevilla.free.fr/gnuplot/ ... et une version C++ à base iostream-est disponible via git (voir: http://www.stahlke.org/dan/gnuplot-iostream/)

Le plus portable et probablement le plus facile De toute façon, il faudrait encore appeler gnuplot pour tracer un script. Comme sje397 mentionné, vérifiez votre documentation pour l'appel system() dans stdlib.h. Sur une note, il y a aussi GNU plotutils, qui offre libplot, une bibliothèque pour tracer des jeux de données, que vous pouvez utiliser dans votre application. Voir: http://www.gnu.org/software/plotutils/

+1

Im pas fantastique à comprendre toute cette documentation, mais j'ai trouvé la déclaration pour system(): int système (const char * commande); Est-il donc juste un cas d'ajouter quelque chose comme ceci?: système (gnuplot plot "data_set.dat" avec 1: 2 en utilisant des lignes); – JMzance

+1

À la fin je suis allé quelque chose comme ceci: – JMzance

+1

#include "gnuplot_i.h" int main (vide) { FICHIER * outFichier; OutFile = fopen ("Flight_Path.dat", "w") /* Boucle itérative qui imprime dans le fichier de sortie: example.dat */ fclose (outFile); gnuplot_ctrl * k; k = gnuplot_init(); gnuplot_set_xlabel (k, "x"); gnuplot_set_ylabel (k, "y"); gnuplot_cmd (k, entrée_x); gnuplot_cmd (k, entrée_y); gnuplot_cmd (k, "set title \" Trajectoire avec Drag \ ""); gnuplot_cmd (k, "complot \" Flight_Path.dat \ » en utilisant 1: 2 titre \ "Flight Path \" avec des lignes, \ sommeil (7); gnuplot_close (k); return 0;} – JMzance

2

Bien que je l'ai vu beaucoup de façons de le faire, la façon la plus simple de le faire serait en utilisant la fonction system() (à partir stdlib.h) en C. d'abord faire une gnuplot script et enregistrez-le sous "name.gp" (ni le nom ni l'extension ne comptent).
Un script simple serait,

plot 'Output.dat' with lines 

Après avoir enregistré ce fichier script, il suffit d'ajouter
system("gnuplot -p 'name.gp'");
à la fin de votre code.
C'est aussi simple que ça.

0

J'ai adapté la réponse acceptée pour tracer un tableau flottant tout en évitant l'utilisation d'un fichier temporaire. Dans ce, float* data_ est le tableau et size_t size_ sa taille. J'espère que c'est utile pour quelqu'un!

Cheers,
Andres

void plot(const char* name="FloatSignal"){ 
    // open persistent gnuplot window 
    FILE* gnuplot_pipe = popen ("gnuplot -persistent", "w"); 
    // basic settings 
    fprintf(gnuplot_pipe, "set title '%s'\n", name); 
    // fill it with data 
    fprintf(gnuplot_pipe, "plot '-'\n"); 
    for(size_t i=0; i<size_; ++i){ 
    fprintf(gnuplot_pipe, "%zu %f\n", i, data_[i]); 
    } 
    fprintf(gnuplot_pipe, "e\n"); 
    // refresh can probably be omitted 
    fprintf(gnuplot_pipe, "refresh\n"); 
} 
Questions connexes