Gnuplot et avec quoi il est mangé



Sûrement beaucoup d'entre vous qui feuilletez des publications scientifiques occidentales ont vu des graphiques magnifiques et simples. Peut-être que certains d'entre vous se sont demandé ce que ces experts visualisent leurs données. Et maintenant, il existe un outil graphique magnifique et très simple, qui est presque partout: Windows, Linux, Android et autres, je suis sûr qu'il y en a même sous DOS. Il est fiable, simple et vous permet de présenter toutes les données textuelles sous forme de beaux graphiques.



Pourquoi gnuplot?



Si vous avez déjà lu mes articles " Speedtest simultané sur plusieurs modems LTE ", " Oscillations harmoniques ", " Créer un générateur de nombres aléatoires matériel "), vous avez peut-être remarqué de beaux graphiques.





Graphique de l'article sur le générateur de nombres aléatoires





Image tirée de l'article sur les modems les plus rapides Les



graphiques sont simples et sympas. L'avantage le plus précieux de gnuplot est que pour les tracer, vous n'avez besoin que d'un fichier texte avec les données brutes, gnuplot sur votre système d'exploitation préféré (OpenWRT cependant) et votre éditeur de test vim préféré.



À première vue, il peut sembler que gnuplot est plus difficile à utiliser pour le traçage que MS Excel. Mais il semble seulement que le seuil d'entrée soit un peu plus élevé (vous ne pouvez pas utiliser une souris pour cliquer dessus, vous devez lire la documentation ici), mais en pratique, cela s'avère beaucoup plus facile et plus pratique. J'ai écrit un script une fois et je l'ai utilisé toute ma vie. C'est vraiment beaucoup plus difficile pour moi de tracer un graphique dans Exel, où tout n'est pas logique, que dans gnuplot. Et le principal avantage de gnuplot est que vous pouvez l'intégrer dans vos programmes et visualiser les données à la volée. De plus, gnuplot construit un graphique sans aucun problème à partir d'un fichier de 30 gigaoctets de données statistiques, alors qu'Exel s'est simplement écrasé et n'a pas pu l'ouvrir.



Les avantages de gnuplot incluent le fait qu'il peut être facilement intégré dans le code des langages de programmation standard. Il existe des bibliothèques prêtes à l'emploi pour de nombreux langages, je suis personnellement tombé sur php et python. Ainsi, vous pouvez générer des graphiques directement depuis votre programme.



Par exemple, je dirai que ma bonne amie, lorsqu'elle rédigeait son mémoire, maîtrisait gnuplot (à ma suggestion). Elle n'est jamais technophile, mais elle l'a compris en une soirée. Après cela, elle a construit des graphiques uniquement là-bas, et le niveau de son travail a commencé à différer favorablement par rapport au contexte des collègues utilisant Excel. Pour moi personnellement, les graphiques construits par des programmes spécialisés sont un indicateur de la haute qualité du travail scientifique.



Ainsi, gnuplot est simple, accessible et beau. Allons plus loin.



Gnuplot - Application



Il existe deux façons de travailler avec gnuplot: le mode commande et le mode d'exécution de script. Je recommande d'utiliser le deuxième mode immédiatement, car c'est le plus pratique et le plus rapide. De plus, la fonctionnalité est absolument la même.



Mais pour commencer, nous exécutons gnuplot en mode commande. Exécutez gnuplot à partir de la ligne de commande ou de la manière qui est disponible pour votre système d'exploitation. Vous pouvez commencer à vous entraîner non même en lisant cet article, mais dès la toute première commande d' aide . Elle affichera une aide magnifique et vous pourrez aller plus loin. Mais nous allons passer en revue les faits saillants.



Le graphique est tracé par la commande plot . Une fonction ou un nom de fichier de données peut être spécifié comme paramètres de commande. Ainsi que la colonne de données à utiliser et comment connecter les points, comment les dénoter, etc. Illustrons.



gnuplot> plot sin(x)







Après avoir exécuté la commande, une fenêtre s'ouvrira où il y aura un graphe sinus avec les signatures par défaut. Améliorons ce graphique et trouvons quelques options supplémentaires en même temps.

Signons les axes.



set xlabel "X"


Spécifie l'étiquette de l'axe des abscisses.



set ylabel "Y"


Spécifie l'étiquette de l'axe des ordonnées.



Ajoutons une grille pour montrer où le graphique est construit.



set grid


Je n'aime pas le fait que la sinusoïde sur l'axe des ordonnées repose à la fin du graphique, nous allons donc fixer les limites des valeurs auxquelles le graphique sera limité.



set yrange [-1.1:1.1] 


Ainsi, le graphique sera tracé de la valeur minimale de -1,1 à la valeur maximale de 1,1.

De même, j'ai défini la plage de l'abscisse de sorte qu'une seule période de la sinusoïde soit visible.



set xrange[-pi:pi]


Nous devons ajouter un titre à notre calendrier pour que tout soit Feng Shui.



set title "Gnuplot for habr" font "Helvetica Bold, 20"


Notez que vous pouvez définir les polices et leurs tailles. Consultez la documentation de gnuplot pour savoir quelles polices peuvent être utilisées.



Et enfin, en plus du sinus sur le graphique, dessinons également le cosinus, et définissons également le type de ligne et sa couleur. Et aussi ajouter des légendes, que dessinons-nous.



plot sin(x) title "sinux" lc rgb "red", cos(x)  title "cosinus" lc rgb "green"


Ici, nous dessinons deux graphiques sur une seule toile, en rouge et en vert. En général, il existe de nombreuses options pour les lignes (pointillé, trait, plein), les largeurs de ligne, les couleurs. Ainsi que les types de points. Mon objectif est uniquement de démontrer l'étendue des possibilités. Rassemblons toutes les commandes dans une pile et exécutons-les séquentiellement. Pour réinitialiser les paramètres précédents, entrez reset.



reset
set xlabel "X" 
set ylabel "Y"
set grid
set yrange [-1.1:1.1]
set xrange[-pi:pi]
set title "Gnuplot for habr" font "Helvetica Bold, 20"
plot sin(x) title "sinux"  lc rgb "red", cos(x)  title "cosinus" lc rgb "green"


En conséquence, nous obtenons une telle beauté.





Il n'est plus dommage de publier le calendrier dans une revue scientifique.



Si vous avez honnêtement répété tout cela après moi, vous avez peut-être remarqué que la saisie manuelle à chaque fois, même la copie, n'est en quelque sorte pas comme il faut. Mais est-ce un script prêt à l'emploi? Alors faisons-le!

Quittez le mode commande avec la commande exit et créez un fichier:



vim testsin.gpi


#! /usr/bin/gnuplot -persist
set xlabel "X" 
set ylabel "Y"
set grid
set yrange [-1.1:1.1]
set xrange[-pi:pi]
set title "Gnuplot for habr" font "Helvetica Bold, 20"
plot sin(x) title "sinux"  lc rgb "red", cos(x)  title "cosinus" lc rgb "green"


Nous le rendons exécutable et l'exécutons. Eh bien, n'oubliez pas comment quitter vim.



chmod +x testsin.gpi
./testsin.gpi


En conséquence, nous obtenons la même fenêtre avec des graphiques. Si «-persist» n'est pas ajouté au titre, la fenêtre se fermera automatiquement après l'exécution du script.



Mais il n'est souvent pas très nécessaire de créer une fenêtre, de plus il n'est pas toujours pratique de l'utiliser, et vous pouvez travailler dans un système d'exploitation sans interface graphique. Beaucoup plus souvent, vous devez recevoir des fichiers graphiques. Personnellement, je préfère le format vectoriel postscript, car avec un grand nombre de points, vous pouvez zoomer sur différentes parties du graphique sans perdre en qualité. De plus, le visualiseur sous Linux actualise automatiquement la fenêtre avec le graphique lorsque le fichier PostScript est modifié, ce qui est également très pratique.



Afin de sortir des données dans un fichier et non à l'écran, vous devez réaffecter le terminal.



set terminal png size 800, 600
set output "result.png"


Comme vous pouvez le deviner, nous indiquons le type de fichier, sa résolution, puis nous indiquons le nom du fichier. Ajoutez ces deux lignes au début de notre script, et nous obtenons cette image dans le dossier actuel.







Pour enregistrer au format PostScript, vous devez utiliser les commandes suivantes:



set terminal postscript eps enhanced color solid
set output "result.ps"


Données réelles



Les sinus, les cosinus sont certes sympas à dessiner, mais toujours dessiner des données réelles est bien plus intéressant! Permettez-moi de vous rappeler une tâche récente au sujet de laquelle j'ai écrit un article : afficher des graphiques de la vitesse Internet sur de longues périodes. Le format des données était le suivant.



Opérateur; #Tester; Date; Temps; Coordonnées; Télécharger Mb / s; Télécharger Mb / s; ping; Testeur

Rostelecom; 0; 21/05/2020; 09: 56: 00; NA, NA; 3.7877656948451692; 5.231226008184113; 132.227; MaximaTelecom (Moscou) [0,12 km]: 132,227 ms

Rostelecom; 1; 21/05/2020; 10: 01: 02; NA, NA; 5,274994541394363; 5,1088572634075815; 127,52; MaximaTelecom (Moscou) [0,12 km]: 127,52 ms

Rostelecom; 2; 21/05/2020; 10: 04: 35; NA, NA; 3,61044819424076; 4,624132180211938; T 135e 0,12 km]: 135,456 ms


On peut voir que nous avons un point-virgule comme séparateur, nous devons afficher la vitesse de téléchargement, la vitesse de téléchargement en fonction du temps. De plus, si vous faites attention à la date et l'heure sont dans des colonnes différentes. Maintenant, je vais vous dire comment j'ai contourné cela. Je citerai immédiatement le script par lequel le graphe a été construit.



#! /usr/bin/gnuplot -persist
set terminal postscript eps enhanced color solid
set output "Rostelecom.ps"

#set terminal png size 1024, 768
#set output "Rostelecom.png"
 
set datafile separator ';'
set grid xtics ytics
set xdata time
set timefmt '%d.%m.%Y;%H:%M:%S'

set ylabel "Speed Mb/s"
set xlabel 'Time'
set title "Rostelecom Speed"

plot "Rostelecom.csv" using 3:6 with lines title "Download", '' using 3:7 with lines title "Upload"
 
set title "Rostelecom 2 Ping"
set ylabel "Ping ms"
plot "Rostelecom.csv" using 3:8 with lines title "Ping"


Au début du fichier, nous définissons le fichier de sortie PostScript (ou png, si nécessaire).



définir le séparateur de fichiers de données ';' - nous définissons le caractère délimiteur. Les colonnes sont séparées par des espaces par défaut, mais le fichier csv offre de nombreuses options de délimitation et vous devriez pouvoir toutes les utiliser.

set grid xtics ytics - définissez la grille (vous ne pouvez définir la grille que le long d'un axe).

définir l'heure xdata est un point important, nous parlons du fait que sur l'axe X, le format des données sera l'heure.

set timefmt '% d.% m.% Y;% H:% M:% S ' - définit le format des données d'heure. Veuillez noter que le caractère séparateur de colonne (";") est inclus dans le format de l'heure, nous allons donc traiter deux colonnes comme une seule.



Nous définissons les étiquettes des axes et du graphique. Ensuite, nous construisons un graphique.



tracer "Rostelecom.csv" en utilisant 3: 6 avec le titre des lignes "Télécharger", "en utilisant 3: 7 avec le titre des lignes" Upload " - nous traçons à la fois la vitesse de téléchargement et la vitesse de téléchargement sur un graphique. L'utilisation de 3: 6 est le numéro de colonne de notre fichier de données source, à partir de laquelle nous construisons (X: Y).



Ensuite, nous traçons le graphique ping de la même manière. Le graphique résultant ressemblera à ceci.





Ceci est une capture d'écran de PostScript. Les lignes droites du graphique sont dues au fait qu'il y a des lacunes dans les données. Voici un exemple très réel de tracé.



Et 3D ???



Voulez-vous la 3D? Je les ai!



J'ai longtemps réfléchi à quel exemple de graphisme en trois dimensions donner, et je n'ai rien trouvé de mieux que de visualiser l'image. En effet, par essence, une image est un graphique en trois dimensions, où la luminosité du pixel est la coordonnée z. Alors jouons un petit voyou.

Prenez la photo la plus célèbre d'Einstein.





Et faisons-en un graphique. Pour ce faire, convertissez-le au format pgm ASCII et supprimez tous les espaces, en le remplaçant par une nouvelle ligne, avec une commande aussi simple.



convert Einstein.jpg  -compress none pgm:- | tr -s '\012\015' ' '  | tr -s ' ' '\012'> outfile.pgm 


Pour ceux qui ne comprennent pas ce qui se passe ici, j'explique: nous utilisons imagemagic pour convertir l'image au format pgm, puis nous utilisons tr pour remplacer le retour chariot par une nouvelle ligne vers un espace, puis tous les espaces vers un retour chariot et le sauvegarder dans un fichier. pgm. Toute personne difficile peut ouvrir le fichier dans gimp et l'exporter au format pgm-ASCII.



Après cela, ouvrez le fichier résultant avec notre éditeur préféré vim et supprimez-en le titre. Dans mon cas, ce sont les trois premières lignes. N'oubliez pas de connaître la résolution du fichier à partir du titre, dans ce cas, il était de 325x408 pixels. Ca y est, nous avons un fichier texte de coordonnées Z! Maintenant, notre tâche est d'ajouter les coordonnées X et Y, pour cela, nous allons exécuter tout cela via un script Python.



f = open('outfile.pgm')
for x in range(408):
	for y in range(325):
		line = f.readline()
		print ('%d %d %s' % (x, y, line)),
f.close()


Enregistrez-le sous convert.py et exécutez:



python convert.py > res.txt


Ca y est, maintenant res.txt contient les coordonnées d'Einstein ... Hmm, ou plutôt, les coordonnées de son image. Eh bien, en général, vous voyez l'idée :).



...

406 317 60

406 318 54

406 319 30

406 320 41

406 321 84

406 322 101

406 323 112

406 324 119

407 0 128

407 1 53

407 2 89

407 3 95

407 4 87

...


Exemple de fichier.



Le script pour construire cette beauté ressemble à ceci.



#! /usr/bin/gnuplot -persist
#set terminal png size 1024, 768
#set output "result.png"
#set grid xtics ytics

#set terminal postscript eps enhanced color solid
#set output "result.ps"

set title "Albert Einstein"
set palette gray
set hidden3d
set pm3d at bs
set dgrid3d 100,100 qnorm 2
set xlabel "X" font "Helvetica Bold	,18"
set ylabel "Y" rotate by 90 font "Helvetica Bold	,18"
set zlabel "Z" font "Helvetica Bold	,18"

set xrange [0:408]
set yrange [0:325]
set zrange [-256:256]
unset key 
splot "./res.txt" with l 


Avant de passer à l'analyse du script, si vous répétez ceci, je vous recommande fortement d'exécuter les lignes de script en mode commande afin de pouvoir faire pivoter le graphique avec la souris (bien sûr, sans spécifier le terminal défini). C'est très cool!



Tout d'abord, nous définissons le type de données de sortie, ainsi que les limites des données. Les bordures sont définies en fonction de la taille de l'image, et plus à partir du bas, j'ai espacé 256 caractères le long de l'axe Z afin que la projection de l'image soit visible. Ensuite, nous dirigeons le graphique, étiquetons les axes. Utilisation du raccourci clavier non défini - Je désactive les légendes (ce n'est pas nécessaire sur le graphique). Et voici la vraie magie!



définir la palette gris - nous définissons la palette. S'il est laissé par défaut, le graphique sera coloré comme sur une caméra thermique. Plus la tache est haute, plus jaune, plus le rouge est sombre.



définir hidden3d- comme si tire la surface courbe (supprime les lignes), formant ainsi une belle surface convexe.



set pm3d at bs - activez le style de dessin de données 3D, qui dessine les données avec une coordonnée et une couleur de grille. En savoir plus dans la documentation, une description plus détaillée dépasse le cadre de l'article.



set dgrid3d 100,100 qnorm 2 - définit la taille des cellules de la grille sur 100x100 et l'anticrénelage entre les cellules. La valeur 100x100 est déjà très grande et le programme est très lent. qnorm 2 est l'anti-crénelage (interpolation de données entre les cellules).



splot "./res.txt" avec l - dessine le graphe résultant. "Avec l" signifie dessiner le graphe avec des lignes. C'est un petit hack, car les points sont visibles sur le graphique (de petits points peuvent être définis).



Après le lancement, nous attendons quelque temps, et nous obtenons un "bas-relief" polygonal Essayez de tester les paramètres pour obtenir d'autres options de rendu.





L'image est en mode commande après avoir été tournée.



Une anecdote me vient immédiatement à l'esprit.

Comment trouver la place Lénine?

Seule une personne sans instruction répondra à cette question, qu'il faut multiplier la hauteur de Lénine par la largeur de Lénine.

Une personne éduquée sait prendre une intégrale sur une surface.


Utilisation de gnuplot dans vos programmes



L'exemple est tiré de stackoverflow avec mes modifications mineures.



Le code génère un fichier texte et provoque constamment la reconstruction du graphique. Je vais attacher le code sous le spoiler pour ne pas déchirer l'article.



Exemple de code C utilisant gnuplot
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


float s=10.;
float r=28.;
float b=8.0/3.0;
/* Definimos las funciones */
float f(float x,float y,float z){
    return s*(y-x);
}
float g(float x,float y,float z){
    return x*(r-z)-y;
}
float h(float x,float y,float z){
    return x*y-b*z;
}
FILE *output;
FILE *gp;

int main(){
    gp = popen("gnuplot -","w");
    output = fopen("lorenzgplot.dat","w");
    float t=0.; 
    float dt=0.01;
    float tf=30;
    float x=3.;
    float y=2.;
    float z=0.;
    float k1x,k1y,k1z, k2x,k2y,k2z,k3x,k3y,k3z,k4x,k4y,k4z;
    fprintf(output,"%f %f %f \n",x,y,z);
    fprintf(gp, "splot './lorenzgplot.dat' with lines \n");
/* Ahora Runge Kutta de orden 4 */  
    while(t<tf){
        /* RK4 paso 1 */
        k1x = f(x,y,z)*dt;
        k1y = g(x,y,z)*dt;
        k1z = h(x,y,z)*dt;
        /* RK4 paso 2 */
        k2x = f(x+0.5*k1x,y+0.5*k1y,z+0.5*k1z)*dt;
        k2y = g(x+0.5*k1x,y+0.5*k1y,z+0.5*k1z)*dt;
        k2z = h(x+0.5*k1x,y+0.5*k1y,z+0.5*k1z)*dt;
        /* RK4 paso 3 */
        k3x = f(x+0.5*k2x,y+0.5*k2y,z+0.5*k2z)*dt;
        k3y = g(x+0.5*k2x,y+0.5*k2y,z+0.5*k2z)*dt;
        k3z = h(x+0.5*k2x,y+0.5*k2y,z+0.5*k2z)*dt;
        /* RK4 paso 4 */
        k4x = f(x+k3x,y+k3y,z+k3z)*dt;
        k4y = g(x+k3x,y+k3y,z+k3z)*dt;
        k4z = h(x+k3x,y+k3y,z+k3z)*dt;
        /* Actualizamos las variables y el tiempo */
        x += (k1x/6.0 + k2x/3.0 + k3x/3.0 + k4x/6.0);
        y += (k1y/6.0 + k2y/3.0 + k3y/3.0 + k4y/6.0);
        z += (k1z/6.0 + k2z/3.0 + k3z/3.0 + k4z/6.0);
        /* finalmente escribimos sobre el archivo */

        fprintf(output,"%f %f %f \n",x,y,z);
        fflush(output); 
        usleep(10000);
        fprintf(gp, "replot \n");
        fflush(gp);
        t += dt;
    }
    fclose(gp);
    fclose(output);
    return 0;
}




Le code fonctionne très simplement, on ouvre un tube:



gp = popen("gnuplot -","w");


Ceci est similaire à la barre verticale dans bash, lorsque nous écrivons une autre commande après une commande, uniquement à l'intérieur du programme. Nous écrivons les données dans le fichier lorenzgplot.dat. Appelez une fois la commande splot dans gnuplot:



fprintf(gp, "splot './lorenzgplot.dat' with lines \n");


Et puis, lors de l'ajout d'un nouveau point, nous reconstruisons le graphe.



fprintf(gp, "replot \n");


En conséquence, nous obtenons une très belle construction lente du Lorenz Attractor. Ci-dessous, une vidéo prise il y a près de dix ans avec un vieil appareil photo, alors ne jurez pas trop. Ce qui est important dans la vidéo, c'est que tout fonctionne très bien sur un matériel aussi ancien que le Nokia N800. Il est souhaitable de le regarder sans son.







Il est important de comprendre que la commande replot consomme très bien la mémoire et le temps processeur, c'est-à-dire qu'un tel tracé ne ralentit pas autant le système. Donc, avec tout l'amour pour gnuplot, ce n'est pas la meilleure façon de l'utiliser. Un autre problème est que cette fenêtre ne peut pas être fermée ou déplacée.



Conclusion



Enfin, je veux montrer une vidéo dans laquelle j'ai rassemblé des centaines de graphiques de la distribution logarithmique aléatoire des enregistrements de particules radioactives, données réelles d'une étude. La vidéo peut et doit être regardée avec du son.







Dans cet article, je ne pourrais même pas dire une millième partie des capacités de ce traceur, sauf que j'ai un peu familiarisé le lecteur avec ce programme. Ensuite, vous devriez chercher vous-même des exemples, lire la documentation sur le site officiel gnuplot.sourceforge.net ou www.gnuplot.info . Assurez-vous de regarder les exemples, il y a beaucoup de choses intéressantes et utiles.



Pour commencer, je peux également recommander une brève introduction à gnuplot (rus) . Je suis sincèrement surpris qu'un programme aussi merveilleux ne soit pas étudié dans toutes les universités techniques au même titre que Latex. Pour une raison quelconque, nous avons appris MS Excel et Word.



L'apprentissage de gnuplot n'est pas difficile, j'ai passé littéralement quelques jours à essayer de le comprendre à partir de zéro. Mais avec cet article, je pense que tout sera plus rapide pour vous. Maintenant, j'ai oublié tous les Exel / Calc en tant que traceurs, je n'utilise que gnuplot. De plus, je ne connais même pas un dixième de toutes les possibilités de tracer des graphiques.



Je tiens à noter qu'il existe de nombreux autres traceurs, pas pire que gnuplot, d'autant plus qu'il est assez ancien. Mais pour moi, gnuplot s'est avéré être le plus simple et le plus complet. De plus, c'est le traceur le plus courant et il existe un grand nombre d'exemples d'utilisation sur le Web. Merci d'avoir lu!






All Articles