Représenter graphiquement des données avec Chart

Date de publication:
Durée de lecture estimée:

Il est souvent nécessaire de proposer une représentation graphique d'un jeu de données afin de les rendre plus compréhensibles et faciliter leur analyse. Ce type de traitement est aisément réalisable en Perl à l'aide du module Chart.

Développé par Herbert Breunung, Chart est disponible sous la forme d’un module Perl disponible à l’adresse https://metacpan.org/pod/Chart. Il s’agit d’un framework objet extensible et proposant de nombreuses représentations graphiques. Il est utilisable dans de nombreux contextes tels qu’un outil en ligne de commande, une application graphique ou un service web.

Les différentes représentations graphiques proposées par Chart

Installation de Chart

L’installation de Chart ne pose pas de difficultés particulières. Elle peut être réalisée à l’aide de la commande cpanm de la manière suivante :

cpanm Chart

Bien évidemment, pour tout projet, la bonne pratique consiste à utiliser Carton afin d’éviter des conflits de version entre projets. Si vous optez pour cette solution, le fichier cpanfile aura le contenu suivant :

requires 'Chart','=','2.403.9';

L’installation de ce module est rapide mais notez que sous Linux, certaines dépendances peuvent être absentes de votre système d’exploitation et bloquer la compilation de Chart. Sous Debian, le problème concerne les paquets pkg-config et libgd-dev (https://libgd.github.io). Dans ce cas, vous devez ajouter préalablement les paquets manquants :

sudo apt-get install pkg-config libgd-dev

Sous Microsoft Windows, l’installation se déroule à la perfection avec Strawberry Perl.

Générer un graphique simple

De base, le module Chart propose 13 représentations graphiques qui sont Points, Lines, Bars, LinesPoints, Composite, StackedBars, Mountain, Pie, HorizontalBars, Split, ErrorBars, Pareto et Direction. Dans votre code, vous avez le choix entre charger toutes les classes à l’aide de la directive use Chart ou uniquement celles qui seront utilisées. L’exemple suivant autorise uniquement l’usage des représentations graphique Bars et Lines :

use Chart::Bars;
use Chart::Lines;

Vous devez ensuite définir les données du graphique. Pour cela, il faut construire un tableau qui regroupe tout d’abord les intitulés des données et ensuite les valeurs associées (dataset).

my @data = ( 
    [ 'Pommes', 'Poires', 'Scoubidous' ],
    [ 45, 30, 62 ]
);

L’étape suivante consiste à initialiser la représentation graphique en l’instanciant. Le constructeur peut recevoir en arguments les dimensions de l’image produite. Dans l’exemple ci-dessous, pour générer un histogramme, Chart utilisera une surface de dessin mesurant 600 pixels pour sa largeur et 400 pixels pour sa hauteur :

my $chart = Chart::Bars->new(600,400);

$chart->png('ventes.png',\@data);

Nous produisons ainsi une image au format PNG, construite à partir des données du tableau @data et enregistrée dans le fichier ventes.png.

Personnaliser la représentation graphique

Ce premier essai permet certes d’obtenir une représentation graphique mais il y a un certain nombres d’ajustements à faire avant de pouvoir exploiter le résultat. En effet, la lecture du graphique est faussée par le fait que l’axe des ordonnées ne commence pas à 0. De plus, il n’y a aucune légende ou intitulé.

Pour résoudre ces difficultés, Chart propose un vaste ensemble de propriétés permettant de finaliser une représentation graphique. Ces propriétés sont appliquées à l’instance du graphique à l’aide de la méthode set. Commençons par préciser que les valeurs sur l’axe des ordonnées débutent à 0 en fixant la valeur de la propriété min_val. Profitons en également pour indiquer à Chart que les valeurs sont entières avec la propriété precision.

my @legend = ('Produits');

my $chart = Chart::Bars->new(600,400);

$chart->set ( 
    min_val => 0,
    precision =>  0
);

$chart->png('ventes.png',\@data);

Déclarons la légende en indiquant que les pommes, les poires et les scoubidous sont des produits. La legende est définie à l’aide d’un tableau afin qu’elle puisse être composée de plusieurs intitulés.

my @legend = ('Produits');

$chart->set ( 
    min_val => 0,
    precision =>  0,
    legend_labels => \@legend
);

Afin de rendre le graphique explicite, ajoutons un titre et des intitulés sur les axes.

$chart->set ( 
    min_val => 0,
    precision =>  0,
    title => 'Rapport des ventes',
    x_label => 'Produits', 
    y_label => 'Nombre',
    legend_labels => \@legend
);

Une première version exploitable du graphique

Séries multiples

Faisons évoluer la représentation afin de connaître la répartition des ventes en fonction du public d’acheteurs. Il s’agit ici de savoir ce que les hommes et les femmes préfèrent. Pour cela, il faut modifier le tableau data pour distinguer les ventes en fonction du sexe.

my @data = ( 
    [ 'Pommes', 'Poires', 'Scoubidous' ],
    [ 25, 10, 30 ],
    [ 20, 20, 32 ]
);

Le premier jeu de valeur correspond aux hommes et le second aux femmes. Modifions également la déclaration de la légende pour faire correspondre chaque série de valeurs à son intitulé.

my @legend = ('Hommes','Femmes');

Nous obtenons maintenant un graphique où les ventes de chaque produit sont représentées par deux histogrammes.

Ajout d'une second série

Graphique à double entrée

Le cahier des charges évolue une nouvelle fois et il nous est demandé de faire apparaître le nombre de ventes total pour chaque produit. La solution est de définir un tableau à double entrée et d’utiliser un graphique en ligne, superposé aux histogrammes, pour représenter les ventes totales.

Pour faire cela, nous devons utiliser la classe Chart::Composite permettrant de combiner différents types de graphiques sur une seule représentation graphique.

use Chart::Composite;

Nous devons modifier la déclaration des séries de valeurs pour déclarer les valeurs totales.

my @data = ( 
    [ 'Pommes', 'Poires', 'Scoubidous' ],
    [ 25, 10, 30 ],
    [ 20, 20, 32 ],
    [ 45, 30, 62 ]
);

Comme précisé précédemment, la classe Chart::Bar est remplacé par Chart::Composite. La légende est mise à jour afin de préciser l’intitulé de la série contenant les valeurs totales. Dans les propriétés, nous ajoutons y_label2 afin de préciser la signification de l’axe des ordonnées situé à droite du graphique. La propriété composite_info permet de spécifier le type de représentation graphique utilisé pour chacune des séries. La classe Chart::Bar est utilisée pour la première et la seconde série de valeurs. La classe Chart::LinePoints est utilisée pour la troisième série de valeur.

my $chart = Chart::Composite->new(600,400);

my @legend = ('Hommes','Femmes','Total');

$chart->set ( 
    min_val => 0,
    precision =>  0,
    title => 'Rapport des ventes',
    x_label => 'Produits', 
    y_label => 'Nombre',
    legend_labels => \@legend,
    y_label2 => 'Total',
    composite_info => [ 
        [ 'Bars', [ 1, 2 ] ], 
        [ 'LinesPoints', [ 3 ] ]  
    ]
);

$chart->png('chart_4.png',\@data);

Graphique à double entrée

Conclusion

Chart est un module simple d’utilisation et extrêmement puissant pour représenter graphiquement des données. N’hésitez pas à explorer de manière exhaustive les propriétés car elles vous permettront d’obtenir des résultats époustouflants avec quelques lignes de code Perl.