data-visualization

Par anthropics · knowledge-work-plugins

Créez des visualisations de données efficaces avec Python (matplotlib, seaborn, plotly). À utiliser lors de la construction de graphiques, du choix du type de graphique adapté à un jeu de données, de la création de figures de qualité publication, ou de l'application de principes de design comme l'accessibilité et la théorie des couleurs.

npx skills add https://github.com/anthropics/knowledge-work-plugins --skill data-visualization

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

Skills similaires