Chapitre 5 – Une alternative à gnuplot : le format SVG
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-05.pdf
(Limite 50000 octets — symratio=0.40, minlen=20, clean)
Révision : brouillon 5 Une alternative à gnuplot : le format SVG 6 Une alternative à gnuplot : le format SVG 6.2 Image matricielle et image vectorielle . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 Un fichier SVG est un fichier texte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4 Créer notre premier SVG depuis C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.6 Le système de coordonnées SVG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.7 Tracer les axes d’un graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.8 Du système mathématique au système graphique . . . . . . . . . . . . . . . . . . . . 6.9 La transformation verticale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.10 Écrire les transformations en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.12 Tracer une courbe avec des segments . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.13 Une solution plus naturelle : polyline . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.15 Ajouter des graduations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.18 Le navigateur devient notre afficheur . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.19 Séparer les données et leur représentation . . . . . . . . . . . . . . . . . . . . . . . . . 6.20 Vers une classe GraphiqueSVG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.21 Pourquoi ne pas tout programmer nous-mêmes ? . . . . . . . . . . . . . . . . . . . . . 6.22 Deux approches complémentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.23 Application aux simulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Révision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVGAccueilRévision : brouillon Une alternative à gnuplot : le format Révision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVGAccueilRévision : brouillon Une alternative à gnuplot : le format Dans le chapitre précédent, nous avons utilisé gnuplot pour transformer les résultats numériques d’un programme C++ en représentations graphiques, cette approche repose sur une séparation claire : C++ −→ fichier de données −→ gnuplot −→ graphique Elle est particulièrement efficace lorsque gnuplot est disponible. Mais il existe une autre possibilité : demander directement au programme C++ de produire luimême un fichier graphique, nous allons pour cela utiliser le format SVG, qui signifie Scalable Vector Il s’agit d’un format graphique vectoriel décrit par du texte. Cette dernière propriété est essentielle pour nous. Puisqu’un fichier SVG est constitué de texte, nous pouvons le créer avec les outils d’entrée/sortie que nous connaissons déjà : std::ofstream fichier("graphique.svg"); Nous allons ainsi passer directement de : C++ −→ fichier SVG −→ graphique sans utiliser de bibliothèque graphique particulière. Image matricielle et image vectorielle Une image matricielle, comme une image PNG ou JPEG, est constituée d’une grille de pixels. Une image vectorielle est décrite autrement. Elle contient des objets géométriques : • des rectangles ; Révision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG Le fichier indique leurs positions, leurs dimensions et certaines de leurs propriétés. Par exemple, au lieu de mémoriser tous les pixels constituant un cercle, un fichier vectoriel peut essentiellement indiquer : centre, rayon, contour, remplissage. Cette représentation possède un avantage important : l’image peut être agrandie sans devenir composée de gros pixels visibles. C’est l’origine du mot : dans Scalable Vector Graphics. Un fichier SVG est un fichier texte Considérons le fichier suivant : <svg xmlns="http://www.w3.org/2000/svg" Il décrit une image SVG de : La première balise ouvre le document SVG : Entre ces deux balises, nous pouvons placer les objets graphiques. Nous n’allons pas étudier SVG comme un langage à part entière. Nous utiliserons uniquement les quelques éléments nécessaires à la construction de graphiques scientifiques simples. Créer notre premier SVG depuis C++ Un programme C++ peut écrire directement ce texte : std::ofstream fichier("graphique.svg");AccueilRévision : brouillon 2026 - C++ Partie III fichier << "</svg>\n"; Une alternative à gnuplot : le format SVG << "Impossible de creer le fichier.\n"; << "<svg xmlns=\"http://www.w3.org/2000/svg\" " << "width=\"600\" height=\"400\">\n"; Le programme crée un fichier : qui représente pour l’instant une image vide. Remarquons l’utilisation de : dans les chaînes de caractères C++. délimite normalement une chaîne. Pour placer ce caractère à l’intérieur de la chaîne elle-même, il doit donc être précédé de : SVG possède un élément permettant de tracer un segment. <line x1="50" y1="100" Le premier point possède les coordonnées : indique la couleur du trait. Depuis C++, nous pouvons donc écrire :AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG << "<line x1=\"50\" y1=\"100\" " << "x2=\"500\" y2=\"100\" " << "stroke=\"black\" />\n"; Le système de coordonnées SVG Le système de coordonnées utilisé par SVG demande une attention particulière. L’origine se trouve dans le coin supérieur gauche de l’image. L’axe horizontal est orienté vers la droite. Mais l’axe vertical est orienté vers le bas. x augmente vers la droite, y augmente vers le bas. Cette convention est courante dans les systèmes graphiques informatiques. Elle est cependant différente de celle que nous utilisons habituellement en mathématiques, où l’axe vertical est orienté vers le haut. Nous devrons tenir compte de cette différence lors de la transformation de nos données en coordonnées Tracer les axes d’un graphique Prenons une image de : et réservons une marge de 60 unités autour du graphique. L’axe horizontal peut être tracé avec : << "<line x1=\"60\" y1=\"540\" " << "x2=\"740\" y2=\"540\" " << "stroke=\"black\" />\n"; et l’axe vertical avec : << "<line x1=\"60\" y1=\"60\" " << "stroke=\"black\" />\n"; La zone réellement disponible pour les données possède alors une largeur :AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG Du système mathématique au système graphique Supposons que les valeurs de x appartiennent à l’intervalle : x min ≤ x ≤ x max . Nous voulons transformer cet intervalle en coordonnées graphiques comprises entre : La transformation est : (X max − X min ) . Cette formule effectue trois opérations. L’origine de l’intervalle est ainsi déplacée vers zéro. transforme l’intervalle en : Enfin, on multiplie par la largeur graphique disponible et on ajoute la marge de gauche. Cette transformation constitue un changement d’échelle accompagné d’une translation. La transformation verticale Pour l’axe vertical, la situation est légèrement différente. Dans le système mathématique, y augmente vers le haut. Dans SVG, Y augmente vers le bas. Nous devons donc inverser l’axe. Une transformation possible est : correspond au bas du graphique, tandis que : correspond au haut du graphique. Cette formule réalise donc simultanément :AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG • une translation ; • un changement d’échelle ; • une inversion de l’axe vertical. Écrire les transformations en C++ Nous pouvons naturellement transformer ces formules en fonctions. Pour l’axe vertical : Nous avons maintenant établi le lien entre les coordonnées mathématiques et les coordonnées de Un cercle SVG s’écrit par exemple : Les coordonnées du centre sont données par :AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG représente le rayon. Nous pouvons donc représenter une série de points calculés par C++. double X = convertirX( x, xMin, xMax, XMin, XMax); double Y = convertirY( y, yMin, yMax, YMin, YMax); << "<circle cx=\"" << X << "fill=\"black\" />\n"; Le programme ne produit plus seulement des nombres. Il transforme maintenant directement les résultats numériques en objets graphiques. Tracer une courbe avec des segments Une première méthode pour tracer une courbe consiste à relier chaque point au suivant par un Supposons que nous connaissions deux points consécutifs : Après transformation, nous obtenons : Nous pouvons alors écrire : << "stroke=\"black\" />\n"; En répétant cette opération pour tous les couples de points consécutifs, nous obtenons une courbe. Une solution plus naturelle : polyline SVG fournit également l’élément :AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG qui permet de relier directement une suite de points. points="50,300 100,250 150,180 200,100" contient la suite des coordonnées. Nous pouvons donc construire cette liste depuis une boucle C++. << "<polyline points=\""; for (int i = 0; i <= 100; ++i) double X = convertirX( x, xMin, xMax, XMin, XMax); double Y = convertirY( y, yMin, yMax, YMin, YMax); << "\" fill=\"none\" " << "stroke=\"black\" />\n"; << X << ’,’ << Y << ’ ’; Cette écriture correspond directement à l’idée mathématique d’une courbe représentée par une succession de points. SVG permet également d’insérer du texte. text-anchor="middle"> La position est donnée par :AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG text-anchor="middle" permet ici de centrer le texte autour de sa position horizontale. << "<text x=\"400\" y=\"30\" " << "text-anchor=\"middle\">" << "Fonction y = x^2" Nous pouvons ainsi ajouter : • le nom des axes ; • des valeurs numériques ; Ajouter des graduations Les graduations peuvent également être calculées par le programme. Supposons que l’axe horizontal représente : Nous pouvons placer une graduation pour chaque entier. for (int i = 0; i <= 10; ++i) double X = convertirX( i, 0.0, 10.0, XMin, XMax); << "<line x1=\"" << X << "\" stroke=\"black\" />\n"; << "\" text-anchor=\"middle\">" Nous voyons apparaître une idée importante : un graphique est lui-même le résultat d’un calcul. La position des axes, des points, des graduations et des textes peut être déterminée numériquement.AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG Une grille n’est finalement qu’un ensemble de lignes. Pour chaque graduation verticale, on peut tracer une ligne sur toute la hauteur du graphique. De même, les graduations de l’axe vertical peuvent produire des lignes horizontales. << "<line x1=\"" << X << "\" stroke=\"lightgray\" />\n"; Les axes principaux peuvent ensuite être tracés par-dessus. La grille n’est donc pas une fonctionnalité mystérieuse fournie par un logiciel graphique. Elle peut être construite avec les mêmes primitives géométriques que le reste du dessin. Un programme complet Nous pouvons maintenant produire un graphique simple de : entièrement depuis C++. constexpr int largeur = 800;AccueilRévision : brouillon 2026 - C++ Partie III constexpr int hauteur = 600; constexpr double YMin = 60.0; constexpr double YMax = 540.0; constexpr double yMin = 0.0; constexpr double yMax = 100.0; Une alternative à gnuplot : le format SVG constexpr double XMin = 60.0; constexpr double XMax = 740.0; constexpr double xMin = 0.0; constexpr double xMax = 10.0; std::ofstream fichier("graphique.svg"); << "Impossible de creer graphique.svg.\n"; << "<svg xmlns=\"http://www.w3.org/2000/svg\" " << "width=\"" << largeur << "\" " << "height=\"" << hauteur << "\">\n"; << "<rect width=\"100%\" height=\"100%\" " << "fill=\"white\" />\n"; << "<line x1=\"" << XMin << "\" stroke=\"black\" />\n"; << "<line x1=\"" << XMin << "\" stroke=\"black\" />\n"; << "<polyline points=\""; for (int i = 0; i <= 100; ++i) double X = convertirX( x, xMin, xMax, XMin, XMax);AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG double Y = convertirY( y, yMin, yMax, YMin, YMax); << X << ’,’ << Y << ’ ’; << "<text x=\"400\" y=\"30\" " << "text-anchor=\"middle\">" << "Fonction y = x^2" fichier << "</svg>\n"; << "\" fill=\"none\" " << "stroke=\"black\" />\n"; Le programme produit directement : Ce fichier peut ensuite être ouvert avec un logiciel capable d’afficher le format SVG, notamment un Le navigateur devient notre afficheur Cette méthode présente une particularité intéressante. Notre programme C++ ne possède aucune fenêtre graphique. Il ne contient aucune bibliothèque graphique. Il produit simplement un fichier. Le logiciel chargé d’afficher ce fichier interprète ensuite les instructions SVG. La chaîne est donc : calcul C++ −→ texte SVG −→ affichage graphique Le navigateur joue ici uniquement le rôle d’afficheur. La construction du graphique a été réalisée par notre programme. Séparer les données et leur représentation Dans un programme plus important, il ne serait évidemment pas souhaitable de mélanger partout les calculs scientifiques et les instructions SVG. Une première amélioration consiste à conserver les résultats dans un conteneur : std::vector<double> valeurs; Le programme effectue d’abord les calculs. Les résultats sont enregistrés. Dans une seconde étape, une fonction reçoit ces données et produit le fichier SVG. Nous retrouvons ainsi une séparation similaire à celle utilisée avec gnuplot :AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG calcul −→ données −→ représentation La différence est que la dernière étape est maintenant réalisée par notre propre code C++. Vers une classe GraphiqueSVG La génération du fichier SVG se prête naturellement à une organisation orientée objet. Nous pourrions imaginer une classe : const std::string& nomFichier, void ajouterCourbe(...); void ajouterTitre(...); void ajouterAxes(...); Cette classe pourrait prendre en charge : • l’ouverture du fichier ; • les dimensions du graphique ; • la conversion des coordonnées ; • les graduations ; • la fermeture correcte du document SVG. Le constructeur pourrait écrire l’en-tête SVG et le destructeur la balise finale : Nous retrouverions alors une nouvelle application du RAII. La durée de vie de l’objet : correspondrait à la durée de construction du document graphique. Pourquoi ne pas tout programmer nous-mêmes ? Nous venons de montrer qu’il est possible de construire directement un graphique depuis C++. Cela ne signifie pas qu’il soit souhaitable de recréer un logiciel complet de représentation graphique. Un outil comme gnuplot sait déjà gérer de nombreuses opérations complexes : • choix automatique des échelles ;AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG • échelles logarithmiques ; • nombreux types de graphiques ; • multiples formats de sortie. Notre objectif est différent. La génération directe d’un SVG permet de comprendre comment des données numériques deviennent une représentation graphique et offre une solution simple lorsqu’un graphique relativement élémentaire suffit. Pour des représentations scientifiques plus complexes, un logiciel spécialisé reste naturellement préférable. Deux approches complémentaires Nous disposons maintenant de deux méthodes. C++ −→ données −→ gnuplot −→ graphique C++ −→ graphique SVG La première délègue la représentation à un logiciel spécialisé. La seconde donne au programme C++ le contrôle direct de la construction graphique. Il n’existe pas une méthode universellement meilleure. Le choix dépend du problème à résoudre. Application aux simulations Pour une simulation de population, nous pourrions par exemple conserver à chaque génération : • le numéro de la génération ; • la population totale ; • le nombre de naissances ; • le nombre de décès. Une fois la simulation terminée, ces valeurs peuvent être utilisées pour construire une courbe SVG. L’axe horizontal représenterait les générations. L’axe vertical représenterait la population. Plusieurs courbes pourraient également être superposées pour comparer différentes grandeurs. Le graphique devient ainsi une sortie directe de la simulation. SVG est un format graphique vectoriel décrit par du texte. Un programme C++ peut donc produire directement un fichier SVG avec un simple flux : sans utiliser de bibliothèque graphique particulière. Les objets graphiques sont décrits par des éléments tels que :AccueilRévision : brouillon 2026 - C++ Partie III Une alternative à gnuplot : le format SVG Le système de coordonnées SVG possède son origine en haut à gauche et son axe vertical est orienté Pour représenter des données mathématiques, il faut donc transformer les coordonnées du problème en coordonnées graphiques. Cette transformation fait intervenir des translations, des changements d’échelle et une inversion de Le programme peut ensuite construire les axes, les graduations, les points, les courbes et les textes nécessaires à la représentation. Cette approche ne remplace pas un logiciel graphique spécialisé dans toutes les situations. Elle constitue une alternative simple et indépendante qui permet surtout de comprendre précisément comment des données numériques deviennent un graphique. Nous disposons ainsi de deux stratégies complémentaires : déléguer la représentation à gnuplot produire directement un fichier SVG depuis C++.AccueilP3-Chap-05 Une alternative à gnuplot : le format SVGAccueilRévision : brouillon Termes à ajouter au glossaire