Comment Créer un Diagramme en Radar (ou polaire) avec Python ?

Introduction

Un graphique radar (ou graphe polaire) est un excellent outil pour visualiser des données multivariées — par exemple, pour comparer plusieurs indicateurs ou catégories entre différentes entités.

Voici comment en créer un pas à pas en utilisant Matplotlib (et éventuellement Plotly pour l’interactivité).

Graphique Radar de Base avec Matplotlib

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import matplotlib.pyplot as plt
import numpy as np

# Données d’exemple
categories = ['Précision', 'Exactitude', 'Rappel', 'F1-Score', 'Vitesse']
values = [0.9, 0.8, 0.85, 0.88, 0.7]

# Fermer le cercle en répétant la première valeur
values += values[:1]
N = len(categories)

# Calculer les angles pour chaque catégorie
angles = np.linspace(0, 2 * np.pi, N, endpoint=False).tolist()
angles += angles[:1]

# Créer la figure
fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))

# Tracer un axe par catégorie + ajouter les étiquettes
plt.xticks(angles[:-1], categories, color='black', size=12)

# Tracer les étiquettes radiales
ax.set_rlabel_position(30)
plt.yticks([0.2, 0.4, 0.6, 0.8], ["0.2", "0.4", "0.6", "0.8"], color="gray", size=10)
plt.ylim(0, 1)

# Tracer les données
ax.plot(angles, values, linewidth=2, linestyle='solid')
ax.fill(angles, values, 'skyblue', alpha=0.4)

plt.title("Performance du Modèle", size=14, y=1.1)
plt.show()

Graphiques Radar en Python : Comment Créer des Diagrammes en Toiles d’Araignée ou Polaires
Graphiques Radar en Python : Comment Créer des Diagrammes en Toiles d’Araignée ou Polaires

Explication

  • Convertit les catégories en coordonnées angulaires (en radians).
  • Ferme le tracé en répétant le premier élément.
  • Utilise polar=True pour dessiner dans un espace circulaire.
  • Remplit la surface pour une meilleure lisibilité.

Comparer Plusieurs Modèles

Vous pouvez tracer plusieurs ensembles de données sur le même graphique radar :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
model_a = [0.9, 0.8, 0.85, 0.88, 0.7]
model_b = [0.75, 0.82, 0.8, 0.77, 0.9]

# Fermer le cercle
model_a += model_a[:1]
model_b += model_b[:1]

fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))
ax.plot(angles, model_a, 'b-', linewidth=2, label='Modèle A')
ax.fill(angles, model_a, 'b', alpha=0.2)
ax.plot(angles, model_b, 'r-', linewidth=2, label='Modèle B')
ax.fill(angles, model_b, 'r', alpha=0.2)

plt.xticks(angles[:-1], categories)
plt.title("Comparaison de Modèles", size=14, y=1.1)
plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1))
plt.show()

Graphiques Radar en Python : Comment Créer des Diagrammes en Toiles d’Araignée ou Polaires
Graphiques Radar en Python : Comment Créer des Diagrammes en Toiles d’Araignée ou Polaires

Graphique Radar Interactif avec Plotly

Si vous souhaitez des infobulles et une rotation/zoom interactif :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import plotly.graph_objects as go

categories = ['Précision', 'Exactitude', 'Rappel', 'F1-Score', 'Vitesse']
model_a = [0.9, 0.8, 0.85, 0.88, 0.7]
model_b = [0.75, 0.82, 0.8, 0.77, 0.9]

fig = go.Figure()

fig.add_trace(go.Scatterpolar(
    r=model_a,
    theta=categories,
    fill='toself',
    name='Modèle A'
))

fig.add_trace(go.Scatterpolar(
    r=model_b,
    theta=categories,
    fill='toself',
    name='Modèle B'
))

fig.update_layout(
    polar=dict(radialaxis=dict(visible=True, range=[0, 1])),
    showlegend=True,
    title="Graphique Radar Interactif"
)

fig.show()

Graphiques Radar en Python : Comment Créer des Diagrammes en Toiles d’Araignée ou Polaires
Graphiques Radar en Python : Comment Créer des Diagrammes en Toiles d’Araignée ou Polaires

Graphique Radar avec Pygal

Qu’est-ce que Pygal ?

Pygal est une bibliothèque Python qui génère des graphiques SVG interactifs — des graphiques vectoriels indépendants de la résolution, légers et parfaits pour le web ou l’impression.

Vous pouvez exporter les graphiques Pygal sous forme de :

  • Fichiers SVG (interactifs, zoomables, avec infobulles)
  • PNG, PDF, ou HTML intégrable dans le navigateur

Avantages de Pygal

Fonctionnalité Avantage
Syntaxe simple et élégante API très claire, haut niveau, peu de configuration.
Sortie SVG interactive Graphiques légers, scalables et interactifs (infobulles, légendes cliquables).
Intégrable facilement Idéal pour les tableaux de bord ou les pages web (export facile en HTML).
Léger Ne dépend pas de gros fichiers JavaScript (contrairement à Plotly).
Haute résolution Les SVG se redimensionnent parfaitement pour les présentations ou impressions.
Hors ligne et statique Ne nécessite ni serveur ni JavaScript — fonctionne hors connexion.

Installer Pygal

Dans votre terminal ou notebook :

1
pip install pygal

Si vous utilisez Jupyter Notebook, vous pouvez aussi exécuter :

1
!pip install pygal

Puis tester l’importation :

1
2
import pygal
print(pygal.__version__)

Si cela fonctionne, Pygal est prêt à être utilisé.

Exemple : Graphique Radar avec Pygal

Voici un exemple minimal :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import pygal
from pygal.style import LightStyle

# Données d’exemple
categories = ['Précision', 'Exactitude', 'Rappel', 'F1-Score', 'Vitesse']

radar_chart = pygal.Radar(fill=True, style=LightStyle)
radar_chart.title = 'Comparaison de Modèles'

radar_chart.x_labels = categories

radar_chart.add('Modèle A', [0.9, 0.8, 0.85, 0.88, 0.7])
radar_chart.add('Modèle B', [0.75, 0.82, 0.8, 0.77, 0.9])

# Afficher dans le navigateur ou exporter
radar_chart.render_in_browser()
# ou enregistrer en SVG
radar_chart.render_to_file('comparaison_modeles.svg')

💡 Astuce : render_in_browser() ouvre le graphique dans votre navigateur par défaut.
Le fichier SVG généré est entièrement interactif — survolez les points pour afficher les valeurs.

Comparaison avec d’Autres Bibliothèques

Bibliothèque Interactivité Type de sortie Points forts Quand l’utiliser
Matplotlib Statique PNG/PDF Hautement personnalisable, précision scientifique Graphiques statiques pour publications
Plotly Élevée HTML/JS Interactivité complète pour tableaux de bord Exploration de données ou applications Dash
Pygal Moyenne SVG Léger, esthétique, facile à intégrer Visualisations statiques ou web légères

Quand Utiliser Pygal

  • Vous souhaitez des visuels interactifs mais légers (sans dépendances lourdes).
  • Vous voulez intégrer vos graphiques dans un blog, un rapport ou une page web statique.
  • Vous préférez une syntaxe simple et déclarative sans configuration complexe.
  • Vous avez besoin d’une qualité vectorielle (PDF, présentations, impressions).

Références

Liens Site
https://matplotlib.org/stable/gallery/specialty_plots/radar_chart.html Matplotlib — Exemple officiel de graphique radar
https://plotly.com/python/radar-chart/ Plotly — Documentation officielle du graphique radar
http://www.pygal.org/en/stable/documentation/types/radar.html Pygal — Documentation officielle du graphique radar

Ancienne Version

Exemple intéressant de graphique en radar (radar chart) avec matplotlib réalisé par Nicolas P. Rougier.

Code source:

Exemple de graphique en radar (radar chart) avec matplotlib (#radar #matplotlib)
Exemple de graphique en radar (radar chart) avec matplotlib (#radar #matplotlib)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (C) 2011  Nicolas P. Rougier
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
# * Neither the name of the glumpy Development Team nor the names of its
#   contributors may be used to endorse or promote products derived from this
#   software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# -----------------------------------------------------------------------------
import numpy as np
import matplotlib
import matplotlib.path as path
import matplotlib.pyplot as plt
import matplotlib.patches as patches


# Data to be represented
# ----------
properties = ['property 1', 'property 2', 'property 3', 
              'property 4', 'property 5', 'property 6',
              'property 7', 'property 8', 'property 9']
values = np.random.uniform(5,9,len(properties))
# ----------


# Choose some nice colors
matplotlib.rc('axes', facecolor = 'white')


# Make figure background the same colors as axes 
fig = plt.figure(figsize=(10,8), facecolor='white')

# Use a polar axes
axes = plt.subplot(111, polar=True)

# Set ticks to the number of properties (in radians)
t = np.arange(0,2*np.pi,2*np.pi/len(properties))
plt.xticks(t, [])

# Set yticks from 0 to 10
plt.yticks(np.linspace(0,10,11))


# Draw polygon representing values
points = [(x,y) for x,y in zip(t,values)]
points.append(points[0])
points = np.array(points)
codes = [path.Path.MOVETO,] + \
        [path.Path.LINETO,]*(len(values) -1) + \
        [ path.Path.CLOSEPOLY ]
_path = path.Path(points, codes)
_patch = patches.PathPatch(_path, fill=True, color='blue', linewidth=0, alpha=.1)
axes.add_patch(_patch)
_patch = patches.PathPatch(_path, fill=False, linewidth = 2)
axes.add_patch(_patch)


# Draw circles at value points
plt.scatter(points[:,0],points[:,1], linewidth=2,
            s=50, color='white', edgecolor='black', zorder=10)

# Set axes limits
plt.ylim(0,10)


# Draw ytick labels to make sure they fit properly
for i in range(len(properties)):
    angle_rad = i/float(len(properties))*2*np.pi
    angle_deg = i/float(len(properties))*360
    ha = "right"
    if angle_rad < np.pi/2 or angle_rad > 3*np.pi/2: ha = "left"
    plt.text(angle_rad, 10.75, properties[i], size=14,
             horizontalalignment=ha, verticalalignment="center")

    # A variant on label orientation
    #    plt.text(angle_rad, 11, properties[i], size=14,
    #             rotation=angle_deg-90,
    #             horizontalalignment='center', verticalalignment="center")


# Done
plt.savefig('radar-chart.png', facecolor='white')
plt.show()
Image

of