Chapitre 4 – Sorties CSV et gnuplot
Document réservé
Vous consultez actuellement la présentation publique de ce chapitre.
Les documents PDF complets, comprenant les développements théoriques, les exemples détaillés et les exercices, sont disponibles sur demande.
Pour obtenir un accès, contactez-moi via la page Contact en indiquant les domaines qui vous intéressent (C++, ESP-IDF, électronique, etc.).
Source PDF : P3-Chap-04.pdf
(Limite 50000 octets — symratio=0.40, minlen=20, clean)
4 Sorties CSV et gnuplot 4.4 Notre premier fichier de données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7 Ajouter un titre à la courbe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.11 Plusieurs séries dans un même fichier . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.12 Plusieurs courbes sur un même graphique . . . . . . . . . . . . . . . . . . . . . . . . . 4.13 Plusieurs fichiers de données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.14 Commentaires dans un fichier de données . . . . . . . . . . . . . . . . . . . . . . . . . 4.15 Tracer directement une fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.16 Les fichiers de commandes gnuplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.20 Une première chaîne automatisée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.21 Lancer gnuplot depuis le programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.22 Une remarque importante sur std : :system . . . . . . . . . . . . . . . . . . . . . . . . 4.23 Attention à la fermeture des fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.24 Utiliser la portée pour fermer le fichier . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.26 Une échelle logarithmique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.27 Le graphique comme outil d’analyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.28 Préparer les futures simulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.29 Séparer calcul, données et représentation . . . . . . . . . . . . . . . . . . . . . . . . . 2026 - C++ Partie III Gnuplot - Sorties graphiquesAccueilSorties CSV et gnuplot Le format CSV (Comma-Separated Values) est un format texte très simple destiné à enregistrer des données sous forme de tableau. Chaque ligne du fichier correspond à une ligne du tableau et les différentes valeurs sont séparées par un caractère déterminé. Historiquement, ce séparateur est la virgule, d’où le nom du format. Dans les pays où la virgule est utilisée comme séparateur décimal, le point-virgule est cependant fréquemment employé. Un fichier contenant les résultats d’une simulation pourrait par exemple prendre la forme suivante : generation;population;naissances;deces Pour C++, un fichier CSV reste simplement un fichier texte : aucune bibliothèque particulière n’est nécessaire pour en créer un. Il suffit d’organiser les données selon la convention choisie : std::ofstream fichier("population.csv"); << "generation;population;naissances;deces\n"; << generation << ’;’ << population << ’;’ << naissances << ’;’ << deces << ’\n’; L’intérêt du CSV est son caractère très largement exploitable : le fichier obtenu peut être ouvert ou importé dans un tableur, un logiciel scientifique ou un programme d’analyse de données. Il constitue ainsi un excellent moyen de conserver les résultats numériques d’un programme C++ indépendamment de la manière dont ils seront ensuite analysés ou représentés graphiquement. l’utilisation de Gnuplot Dans un chapitre précédent, nous avons appris à enregistrer les résultats d’un programme dans un fichier, par exemple un programme pourrait donné la sortie : 2026 - C++ Partie III Gnuplot - Sorties graphiques Une longue suite de nombres est souvent difficile à interpréter et une représentation graphique permet immédiatement de faire apparaître des propriétés qui seraient beaucoup moins visibles dans un tableau, ces propriétés peuvent être • une croissance ; • une décroissance ; • une oscillation ; • une convergence ; • une relation entre deux grandeurs. Il existe de nombreuses bibliothèques permettant de produire directement des graphiques depuis un programme C++ mais nous allons adopter ici une autre approche : le programme C++ effectuera les calculs et produira les données puis un logiciel spécialisé sera ensuite chargé de leur représentation. Ce programme graphique sera gnuplot, qui est gratuit 1 . La chaîne de travail sera donc : programme C++ −→ données −→ gnuplot −→ graphique Cette séparation entre le calcul et la représentation est particulièrement intéressante dans les programmes scientifiques. Qu’est-ce que gnuplot ? gnuplot est un programme destiné à la représentation graphique de données et de fonctions mathématiques qui peut être utilisé de manière interactive depuis un terminal. Si nécessaire, il peut également exécuter une suite de commandes contenues dans un fichier. Il est ainsi possible de lui demander : • de lire un fichier produit par un programme C++ ; • de choisir les colonnes à représenter ; • de tracer des points ou des courbes ; • d’ajouter des titres et des légendes ; • de régler les axes ; 1. L’installation de gnuplot est laissée aux soins du lecteur. Soyez toutefois prudent si vous utilisez Homebrew : celui-ci gère automatiquement les dépendances des logiciels installés et peut notamment installer sa propre version de Python, indépendamment de celles déjà présentes sur votre système. Si vous utilisez également ESP-IDF pour développer en C++ sur les microcontrôleurs ESP32, veillez à conserver l’environnement Python dédié à la version d’ESP-IDF utilisée. La compatibilité d’ESP-IDF avec les différentes versions de Python dépend en effet de la version du framework. De manière très générale, la règle à retenir est "avant d’installer un outil apparemment anodin, vérifiez ce que son gestionnaire de paquets est susceptible d’installer avec lui" ou encore "les dépendances d’un outil font partie de l’environnement de développement, même lorsqu’on ne les a jamais demandées explicitement."Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques • d’enregistrer le résultat dans un fichier graphique. Une caractéristique importante de gnuplot est qu’il n’a pas besoin de connaître la manière dont les données ont été calculées, il reçoit simplement des valeurs à représenter. Le programme C++ et le programme de représentation restent donc indépendants. Notre premier fichier de données Reprenons le programme du chapitre précédent : std::ofstream fichier("resultats.txt"); << "Impossible d’ouvrir le fichier.\n"; for (int i = 0; i <= 100; ++i) Le fichier contient deux colonnes : La première colonne représente x et la seconde représente : Ce format est volontairement très simple, chaque ligne représente un point : et les deux coordonnées sont séparées par un ou plusieurs espaces.Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques Un premier graphique Après avoir lancé gnuplot, on peut entrer plot "resultats.txt" gnuplot lit alors le fichier et représente les données mais on peut également indiquer explicitement quelles colonnes doivent être utilisées : plot "resultats.txt" using 1:2 colonne 1 −→ axe horizontal colonne 2 −→ axe vertical Nous pourrions donc lire cette commande comme représenter la colonne 2 en fonction de la colonne Les données peuvent être représentées sous différentes formes par exemple, pour afficher uniquement les points, on écrira plot "resultats.txt" using 1:2 with points Pour relier les points par des segments : plot "resultats.txt" using 1:2 with lines Il est également possible d’afficher simultanément les points et les segments : plot "resultats.txt" using 1:2 with linespoints plot "resultats.txt" using 1:2 w lp Le choix dépend naturellement de la signification des données, par exemple, des mesures expérimentales sont souvent représentées par des points et une évolution continue calculée avec un pas suffisamment petit est souvent représentée par une ligne.Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques Ajouter un titre à la courbe Par défaut, gnuplot utilise le nom du fichier comme légende mais on peut choisir un titre plus plot "resultats.txt" using 1:2 \ with lines title "x^2" La légende contient alors : Si aucune légende n’est souhaitée : plot "resultats.txt" using 1:2 \ Le mot title associé à une courbe ne doit pas être confondu avec le titre général du graphique, que nous allons maintenant ajouter. Un graphique doit indiquer clairement ce qu’il représente dans son titre : set title "Fonction y = x^2" Le nom de l’axe horizontal est défini par et celui de l’axe vertical par On peut donc écrire : set title "Fonction y = x^2" plot "resultats.txt" using 1:2 \ with lines title "x^2" La représentation devient immédiatement plus informative.Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques Une grille peut faciliter la lecture des valeurs, elle est activée avec : Elle peut être supprimée avec : Nous utiliserons fréquemment : pour les graphiques scientifiques simples. gnuplot détermine normalement automatiquement les limites des axes mais il est cependant possible de les imposer, par exemple La première commande limite l’axe horizontal à l’intervalle : et la seconde l’axe vertical à : Pour revenir à un ajustement automatique : Il est généralement préférable de laisser gnuplot choisir automatiquement les limites, sauf lorsqu’une échelle particulière facilite l’interprétation ou permet de comparer plusieurs graphiques. Plusieurs séries dans un même fichier Un fichier de données peut naturellement contenir plus de deux colonnes. Modifions notre programme :Accueil2026 - C++ Partie III std::ofstream fichier("resultats.txt"); << "Impossible d’ouvrir le fichier.\n"; for (int i = 0; i <= 100; ++i) Gnuplot - Sorties graphiques Le fichier contient maintenant trois colonnes : On peut représenter x 2 avec : plot "resultats.txt" using 1:2 with lines plot "resultats.txt" using 1:3 with lines Plusieurs courbes sur un même graphique gnuplot permet de représenter plusieurs séries dans une même commande, par exemple : plot "resultats.txt" using 1:2 \ with lines title "x^2", \ "resultats.txt" using 1:3 \ with lines title "x^3" La virgule sépare les deux courbes et le graphique contient maintenant :Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques avec une légende permettant de les distinguer. Cette possibilité sera particulièrement utile pour comparer plusieurs grandeurs issues d’une même Plusieurs fichiers de données Les courbes n’ont pas besoin de provenir du même fichier, on peut également écrire : plot "experience1.txt" using 1:2 \ with lines title "Experience 1", \ "experience2.txt" using 1:2 \ with lines title "Experience 2" Cette organisation est intéressante lorsqu’on souhaite comparer plusieurs expériences ou plusieurs simulations indépendantes. Commentaires dans un fichier de données Un fichier de données peut contenir des commentaires, par défaut, une ligne commençant par : peut servir à documenter le fichier, par exemple : # Simulation de population # colonne 2 : population Ces commentaires rendent le fichier beaucoup plus compréhensible lorsqu’il est consulté ultérieurement et le programme C++ peut naturellement les écrire lui-même : fichier << "# temps population\n"; Un fichier de données peut donc rester simple tout en étant documenté. Tracer directement une fonction gnuplot n’est pas limité à la représentation de fichiers, il peut également tracer directement une fonction mathématique.Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques Dans la syntaxe de gnuplot : représente l’élévation à une puissance. On peut donc comparer les données calculées par notre programme avec la fonction théorique : plot "resultats.txt" using 1:2 \ with points title "C++", \ x**2 with lines title "Theorie" Les points proviennent du fichier créé par C++, tandis que la ligne est calculée directement par Cette possibilité est particulièrement utile pour comparer des résultats numériques ou expérimentaux à une expression théorique. Les fichiers de commandes gnuplot Entrer manuellement les commandes dans gnuplot est pratique pour faire des essais, mais dès qu’un graphique comporte plusieurs réglages, il est préférable de conserver ces commandes dans un fichier. Créons par exemple : set title "Fonction y = x^2" plot "resultats.txt" using 1:2 \ with lines title "x^2" gnuplot peut ensuite exécuter ce fichier depuis un terminal en lançant : gnuplot graphique.gp Nous avons maintenant deux fichiers distincts : Le premier contient les données et le second décrit leur représentation. Cette séparation est très utile : on peut modifier le graphique sans recalculer les données.Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques Exporter un graphique Jusqu’à présent, nous avons surtout utilisé gnuplot pour afficher un graphique à l’écran cependant un graphique doit souvent être enregistré dans un fichier. Il faut alors choisir un terminal gnuplot (le terme terminal désigne ici le type de sortie graphique utilisé), par exemple, pour produire une image set terminal pngcairo size 1200,800 set output "graphique.png" On effectue ensuite le tracé : plot "resultats.txt" using 1:2 \ with lines title "x^2" Le graphique est alors écrit dans : plutôt que simplement affiché à l’écran. Pour un document scientifique ou un document LaTeX, le format PDF est particulièrement intéressant. Pour le faire on peut programmer set terminal pdfcairo set output "graphique.pdf" plot "resultats.txt" using 1:2 \ with lines title "x^2" Le graphique obtenu peut ensuite être directement inséré dans un document LaTeX. Cette méthode permet de conserver une excellente qualité graphique, notamment pour les textes et Un fichier de commandes pourrait finalement contenir : set terminal pdfcairo set output "graphique.pdf" set title "Fonction y = x^2" plot "resultats.txt" using 1:2 \Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques with lines title "x^2" Le travail est maintenant clairement séparé et le programme C++ produit : décrit la représentation. gnuplot produit finalement : Une première chaîne automatisée Nous pouvons aller un peu plus loin, le programme C++ peut lui-même produire le fichier de commandes gnuplot. std::ofstream script("graphique.gp"); << "Impossible de creer le script gnuplot.\n"; script << "set terminal pdfcairo\n"; script << "set output \"graphique.pdf\"\n"; script << "set title \"Fonction y = x^2\"\n"; script << "set xlabel \"x\"\n"; script << "set ylabel \"y\"\n"; 16 script << "set grid\n"; << "plot \"resultats.txt\" " << "using 1:2 with lines " << "title \"x^2\"\n"; Le programme C++ produit alors deux fichiers : Le premier contient les résultats numériques et le second contient les instructions nécessaires à leurAccueil2026 - C++ Partie III Gnuplot - Sorties graphiques Lancer gnuplot depuis le programme Il est également possible de demander au programme C++ de lancer gnuplot. Une solution simple consiste à utiliser : std::system("gnuplot graphique.gp"); La chaîne devient alors : C++ −→ resultats.txt −→ graphique.gp −→ gnuplot −→ graphique.pdf Le programme peut donc effectuer le calcul et déclencher ensuite automatiquement la production du Une remarque importante sur std : :system demande au système d’exploitation d’exécuter une commande. Elle est très pratique pour nos expériences, mais elle doit être utilisée avec discernement. Il ne faut notamment pas construire une commande à partir d’un texte arbitraire fourni par un utilisateur sans contrôle. Par exemple, une construction du genre : std::string commande = "gnuplot " + nomFourniParUtilisateur; std::system(commande.c_str()); peut devenir dangereuse si le contenu de la chaîne n’est pas maîtrisé et donc, dans nos exemples, la commande sera entièrement déterminée par le programme : std::system("gnuplot graphique.gp"); Nous l’utiliserons donc uniquement dans ce cadre simple. Attention à la fermeture des fichiers Considérons maintenant la succession suivante : std::ofstream fichier("resultats.txt"); // ecriture des donnees std::system("gnuplot graphique.gp"); Il existe ici un problème potentiel car au moment où gnuplot est lancé, l’objet fichier existe encore et il est possible le flux n’ait pas terminé toutes ses écritures vers le fichier physique. gnuplot risque alors de lire un fichier incomplet. Une première solution consiste à fermer explicitement le fichier :Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques std::system("gnuplot graphique.gp"); Mais nous pouvons également exploiter le RAII. Utiliser la portée pour fermer le fichier std::ofstream fichier("resultats.txt"); << "Impossible de creer le fichier.\n"; for (int i = 0; i <= 100; ++i) std::system("gnuplot graphique.gp"); Lorsque l’accolade fermante est atteinte, l’objet fichier est détruit et son destructeur ferme le fichier et donc, lorsque gnuplot est lancé, nous savons donc que le flux C++ a terminé sa durée de vie. Cette construction illustre une nouvelle fois l’intérêt du RAII : la portée du programme exprime directement la durée pendant laquelle la ressource est nécessaire. Un programme complet Nous pouvons maintenant réunir les différentes étapes. std::ofstream fichier("resultats.txt");Accueil2026 - C++ Partie III << "Impossible de creer resultats.txt.\n"; for (int i = 0; i <= 100; ++i) std::ofstream script("graphique.gp"); << "Impossible de creer graphique.gp.\n"; << "set terminal pdfcairo\n" << "set output \"graphique.pdf\"\n" << "set title \"Fonction y = x^2\"\n" << "set xlabel \"x\"\n" << "set ylabel \"y\"\n" << "plot \"resultats.txt\" " << "using 1:2 with lines " << "title \"x^2\"\n"; std::system("gnuplot graphique.gp"); << "Erreur lors de l’execution de gnuplot.\n"; Gnuplot - Sorties graphiques Le programme produit successivement :Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques Le graphique constitue donc désormais une véritable sortie du programme. Une échelle logarithmique Certaines données évoluent sur plusieurs ordres de grandeur et dans ce cas une échelle logarithmique peut alors être plus informative qu’une échelle linéaire. Pour rendre l’axe vertical logarithmique : Pour les deux axes : Pour revenir à une échelle linéaire : Les échelles logarithmiques sont particulièrement utiles pour observer certaines croissances, décroissances ou lois de puissance. Le graphique comme outil d’analyse Un graphique n’est pas uniquement destiné à présenter un résultat final mais constitue également un outil d’analyse lors du développement d’une simulation. On peut enregistrer à chaque étape différentes grandeurs 2 : • la population totale ; • le nombre de naissances ; • le nombre de décès ; • une valeur moyenne ; • une distribution. La représentation graphique permet alors de détecter rapidement un comportement inattendu. Une population qui explose brusquement, une grandeur qui devient négative ou une oscillation imprévue peuvent révéler une erreur dans le modèle ou dans le programme. Le graphique devient ainsi un instrument permettant d’observer le fonctionnement du programme lui-même. Préparer les futures simulations Imaginons une simulation de population. À chaque génération, le programme pourrait enregistrer : 2. Voir programme de simulation de Penna. Partie VIAccueil2026 - C++ Partie III Gnuplot - Sorties graphiques # generation population naissances morts Nous pourrions représenter la population avec : plot "population.txt" using 1:2 \ with lines title "Population" ou comparer les naissances et les décès : plot "population.txt" using 1:3 \ with lines title "Naissances", \ "population.txt" using 1:4 \ with lines title "Deces" Le programme de simulation n’a pas besoin de connaître la manière dont ces courbes seront représentées, sa responsabilité est de produire correctement les données. Séparer calcul, données et représentation Nous arrivons ainsi à une organisation générale particulièrement utile : Le programme C++ est responsable du calcul. Le fichier constitue une représentation persistante des résultats. gnuplot est responsable de leur représentation graphique. Cette séparation présente plusieurs avantages. On peut modifier la présentation sans relancer le calcul. On peut représenter différemment les mêmes résultats. On peut conserver les données brutes. On peut utiliser les mêmes données avec un autre logiciel. On peut également automatiser entièrement la chaîne lorsque cela devient nécessaire.Accueil2026 - C++ Partie III Gnuplot - Sorties graphiques • gnuplot permet de représenter graphiquement des données produites par un programme C++ sans intégrer une bibliothèque graphique complexe dans le programme. • Un fichier constitué de plusieurs colonnes numériques suffit pour produire des courbes. plot "resultats.txt" using 1:2 représente la deuxième colonne en fonction de la première. permettent de choisir la forme de la représentation. • Plusieurs colonnes ou plusieurs fichiers peuvent être représentés sur un même graphique. • Les commandes gnuplot peuvent être enregistrées dans un script, ce qui permet de reproduire exactement une représentation. • gnuplot peut également produire directement des fichiers graphiques, notamment PNG • Enfin, un programme C++ peut produire à la fois les données et le script gnuplot, puis lancer celui-ci automatiquement. • Nous disposons alors d’une chaîne complète : C++ −→ données −→ gnuplot −→ graphique • Cette organisation sera particulièrement utile pour les simulations pour lesquelles le programme calculera l’évolution du système, les résultats seront enregistrés dans des fichiers et gnuplot permettra d’en observer immédiatement le comportement.AccueilP3-Chap-04 Gnuplot - Sorties graphiquesAccueilTermes à ajouter au glossaire