Compétence Visualisation de Données
Conseils de sélection de graphiques, motifs de code de visualisation Python, principes de conception et considérations d'accessibilité pour créer des visualisations de données efficaces.
Guide de Sélection de Graphiques
Choisir en Fonction de la Relation de Données
| Ce Que Vous Montrez | Meilleur Graphique | Alternatives |
|---|---|---|
| Tendance dans le temps | Graphique linéaire | Graphique en aires (si composition ou cumul) |
| Comparaison entre catégories | Graphique en barres verticales | Barres horizontales (nombreuses catégories), graphique lollipop |
| Classement | Graphique en barres horizontales | Dot plot, graphique de pente (deux périodes) |
| Composition partie-tout | Graphique en barres empilées | Treemap (hiérarchique), waffle chart |
| Composition dans le temps | Graphique en aires empilées | Barres empilées 100% (pour proportion) |
| Distribution | Histogramme | Box plot (comparaison de groupes), graphique violon, strip plot |
| Corrélation (2 variables) | Scatter plot | Bubble chart (3e variable en taille) |
| Corrélation (nombreuses variables) | Heatmap (matrice de corrélation) | Pair plot |
| Motifs géographiques | Carte choroplèthe | Bubble map, hex map |
| Flux / processus | Diagramme Sankey | Funnel chart (étapes séquentielles) |
| Réseau de relations | Graphique réseau | Chord diagram |
| Performance vs. cible | Bullet chart | Gauge (KPI unique uniquement) |
| Plusieurs KPIs à la fois | Small multiples | Dashboard avec graphiques séparés |
Quand NE PAS Utiliser Certains Graphiques
- Camemberts : À éviter sauf <6 catégories et les proportions exactes importent moins que la comparaison brute. Les humains sont mauvais pour comparer les angles. Utilisez plutôt des graphiques en barres.
- Graphiques 3D : Jamais. Ils déforment la perception et n'ajoutent aucune information.
- Graphiques à double axe : À utiliser avec prudence. Ils peuvent induire en erreur en laissant supposer une corrélation. Étiquetez clairement les deux axes s'ils sont utilisés.
- Graphiques en barres empilées (nombreuses catégories) : Difficile de comparer les segments du milieu. Utilisez plutôt des small multiples ou des barres groupées.
- Graphiques en donut : Légèrement mieux que les camemberts mais mêmes problèmes fondamentaux. À utiliser au maximum pour l'affichage d'un KPI unique.
Motifs de Code de Visualisation Python
Configuration et Style
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import seaborn as sns
import pandas as pd
import numpy as np
# Configuration de style professionnel
plt.style.use('seaborn-v0_8-whitegrid')
plt.rcParams.update({
'figure.figsize': (10, 6),
'figure.dpi': 150,
'font.size': 11,
'axes.titlesize': 14,
'axes.titleweight': 'bold',
'axes.labelsize': 11,
'xtick.labelsize': 10,
'ytick.labelsize': 10,
'legend.fontsize': 10,
'figure.titlesize': 16,
})
# Palettes adaptées aux daltoniens
PALETTE_CATEGORICAL = ['#4C72B0', '#DD8452', '#55A868', '#C44E52', '#8172B3', '#937860']
PALETTE_SEQUENTIAL = 'YlOrRd'
PALETTE_DIVERGING = 'RdBu_r'
Graphique Linéaire (Série Temporelle)
fig, ax = plt.subplots(figsize=(10, 6))
for label, group in df.groupby('category'):
ax.plot(group['date'], group['value'], label=label, linewidth=2)
ax.set_title('Tendance des Métriques par Catégorie', fontweight='bold')
ax.set_xlabel('Date')
ax.set_ylabel('Valeur')
ax.legend(loc='upper left', frameon=True)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# Formater les dates sur l'axe x
fig.autofmt_xdate()
plt.tight_layout()
plt.savefig('trend_chart.png', dpi=150, bbox_inches='tight')
Graphique en Barres (Comparaison)
fig, ax = plt.subplots(figsize=(10, 6))
# Trier par valeur pour faciliter la lecture
df_sorted = df.sort_values('metric', ascending=True)
bars = ax.barh(df_sorted['category'], df_sorted['metric'], color=PALETTE_CATEGORICAL[0])
# Ajouter les étiquettes de valeurs
for bar in bars:
width = bar.get_width()
ax.text(width + 0.5, bar.get_y() + bar.get_height()/2,
f'{width:,.0f}', ha='left', va='center', fontsize=10)
ax.set_title('Métrique par Catégorie (Classée)', fontweight='bold')
ax.set_xlabel('Valeur de la Métrique')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.tight_layout()
plt.savefig('bar_chart.png', dpi=150, bbox_inches='tight')
Histogramme (Distribution)
fig, ax = plt.subplots(figsize=(10, 6))
ax.hist(df['value'], bins=30, color=PALETTE_CATEGORICAL[0], edgecolor='white', alpha=0.8)
# Ajouter les lignes de moyenne et médiane
mean_val = df['value'].mean()
median_val = df['value'].median()
ax.axvline(mean_val, color='red', linestyle='--', linewidth=1.5, label=f'Moyenne : {mean_val:,.1f}')
ax.axvline(median_val, color='green', linestyle='--', linewidth=1.5, label=f'Médiane : {median_val:,.1f}')
ax.set_title('Distribution des Valeurs', fontweight='bold')
ax.set_xlabel('Valeur')
ax.set_ylabel('Fréquence')
ax.legend()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.tight_layout()
plt.savefig('histogram.png', dpi=150, bbox_inches='tight')
Heatmap
fig, ax = plt.subplots(figsize=(10, 8))
# Pivoter les données au format heatmap
pivot = df.pivot_table(index='row_dim', columns='col_dim', values='metric', aggfunc='sum')
sns.heatmap(pivot, annot=True, fmt=',.0f', cmap='YlOrRd',
linewidths=0.5, ax=ax, cbar_kws={'label': 'Valeur de la Métrique'})
ax.set_title('Métrique par Dimension Ligne et Dimension Colonne', fontweight='bold')
ax.set_xlabel('Dimension Colonne')
ax.set_ylabel('Dimension Ligne')
plt.tight_layout()
plt.savefig('heatmap.png', dpi=150, bbox_inches='tight')
Small Multiples
categories = df['category'].unique()
n_cats = len(categories)
n_cols = min(3, n_cats)
n_rows = (n_cats + n_cols - 1) // n_cols
fig, axes = plt.subplots(n_rows, n_cols, figsize=(5*n_cols, 4*n_rows), sharex=True, sharey=True)
axes = axes.flatten() if n_cats > 1 else [axes]
for i, cat in enumerate(categories):
ax = axes[i]
subset = df[df['category'] == cat]
ax.plot(subset['date'], subset['value'], color=PALETTE_CATEGORICAL[i % len(PALETTE_CATEGORICAL)])
ax.set_title(cat, fontsize=12)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# Masquer les sous-graphiques vides
for j in range(i+1, len(axes)):
axes[j].set_visible(False)
fig.suptitle('Tendances par Catégorie', fontsize=14, fontweight='bold', y=1.02)
plt.tight_layout()
plt.savefig('small_multiples.png', dpi=150, bbox_inches='tight')
Aides de Formatage des Nombres
def format_number(val, format_type='number'):
"""Formater les nombres pour les étiquettes de graphiques."""
if format_type == 'currency':
if abs(val) >= 1e9:
return f'${val/1e9:.1f}B'
elif abs(val) >= 1e6:
return f'${val/1e6:.1f}M'
elif abs(val) >= 1e3:
return f'${val/1e3:.1f}K'
else:
return f'${val:,.0f}'
elif format_type == 'percent':
return f'{val:.1f}%'
elif format_type == 'number':
if abs(val) >= 1e9:
return f'{val/1e9:.1f}B'
elif abs(val) >= 1e6:
return f'{val/1e6:.1f}M'
elif abs(val) >= 1e3:
return f'{val/1e3:.1f}K'
else:
return f'{val:,.0f}'
return str(val)
# Utilisation avec formateur d'axe
ax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda x, p: format_number(x, 'currency')))
Graphiques Interactifs avec Plotly
import plotly.express as px
import plotly.graph_objects as go
# Graphique linéaire interactif simple
fig = px.line(df, x='date', y='value', color='category',
title='Tendance de Métrique Interactif',
labels={'value': 'Valeur de la Métrique', 'date': 'Date'})
fig.update_layout(hovermode='x unified')
fig.write_html('interactive_chart.html')
fig.show()
# Scatter interactif avec données de survol
fig = px.scatter(df, x='metric_a', y='metric_b', color='category',
size='size_metric', hover_data=['name', 'detail_field'],
title='Analyse de Corrélation')
fig.show()
Principes de Conception
Couleur
- Utiliser la couleur à bon escient : La couleur doit encoder des données, pas décorer
- Mettre en évidence l'histoire : Utilisez une couleur d'accent vive pour l'insight clé ; griser tout le reste
- Données séquentielles : Utilisez un gradient monochrome (clair à foncé) pour les valeurs ordonnées
- Données divergentes : Utilisez un gradient à deux teintes avec point neutre au milieu pour les données avec un centre significatif
- Données catégorisées : Utilisez des teintes distinctes, maximum 6-8 avant que ce devienne confus
- Éviter rouge/vert uniquement : 8 % des hommes souffrent de daltonisme rouge-vert. Utilisez bleu/orange comme paire principale
Typographie
- Le titre énonce l'insight : « Les revenus ont augmenté de 23 % en glissement annuel » vaut mieux que « Revenus par Mois »
- Le sous-titre ajoute du contexte : Plage de dates, filtres appliqués, source des données
- Les étiquettes d'axes sont lisibles : Jamais à 90 degrés si évitable. Raccourcissez ou enveloppez plutôt
- Les étiquettes de données ajoutent de la précision : Utilisez sur les points clés, pas sur chaque barre
- L'annotation en évidence : Appelez l'attention sur des points spécifiques avec des annotations texte
Disposition
- Réduire le bruit du graphique : Supprimez les grilles, bordures, arrière-plans qui ne transmettent pas d'information
- Trier de manière significative : Catégories triées par valeur (pas alphabétiquement) sauf s'il y a un ordre naturel (mois, étapes)
- Rapport d'aspect approprié : Les séries temporelles plus larges que hautes (3:1 à 2:1) ; les comparaisons peuvent être plus carrées
- L'espace blanc est bon : Ne tassez pas les graphiques ensemble. Donnez à chaque visualisation de l'espace pour respirer
Exactitude
- Les graphiques en barres commencent à zéro : Toujours. Une barre de 95 à 100 exagère une différence de 5 %
- Les graphiques linéaires peuvent avoir des lignes de base non nulles : Quand la plage de variation est significative
- Échelles cohérentes sur les panneaux : Lors de la comparaison de plusieurs graphiques, utilisez la même plage d'axe
- Montrer l'incertitude : Barres d'erreur, intervalles de confiance ou plages quand les données sont incertaines
- Étiqueter vos axes : Ne faites jamais deviner au lecteur ce que les nombres signifient
Considérations d'Accessibilité
Daltonisme
- Ne jamais dépendre de la couleur seule pour distinguer les séries de données
- Ajouter des remplissages à motif, différents styles de lignes (solide, pointillé, pointé) ou des étiquettes directes
- Tester avec un simulateur de daltonisme (ex. : Coblis, Sim Daltonism)
- Utiliser la palette adaptée aux daltoniens :
sns.color_palette("colorblind")
Lecteurs d'écran
- Inclure du texte alternatif décrivant l'insight clé du graphique
- Fournir une alternative de table de données aux côtés de la visualisation
- Utiliser des titres et étiquettes sémantiques
Accessibilité Générale
- Contraste suffisant entre les éléments de données et l'arrière-plan
- Taille de texte minimum 10 pt pour les étiquettes, 12 pt pour les titres
- Éviter de transmettre l'information uniquement par position spatiale (ajoutez des étiquettes)
- Considérer l'impression : le graphique fonctionne-t-il en noir et blanc ?
Liste de Vérification d'Accessibilité
Avant de partager une visualisation :
- [ ] Le graphique fonctionne sans couleur (motifs, étiquettes ou styles de lignes différencient les séries)
- [ ] Le texte est lisible au niveau de zoom standard
- [ ] Le titre décrit l'insight, pas seulement les données
- [ ] Les axes sont étiquetés avec unités
- [ ] La légende est claire et positionnée sans obscurcir les données
- [ ] La source de données et la plage de dates sont notées