2. Chapitre 2 : Visualisation
2.1. Introduction
La visualisation de données est l’art de représenter l’information de manière graphique pour faciliter la compréhension, l’exploration et la communication des insights. Ce chapitre couvre les techniques de visualisation essentielles en Python et R.
2.2. Définition et importance
Définition : La visualisation de données consiste à représenter les données dans un format graphique pour fournir un moyen accessible de voir et comprendre les tendances, les valeurs aberrantes et les patterns.
Importance :
Simplification : Rend les informations complexes plus accessibles
Amélioration de la compréhension : Les visuels facilitent l’apprentissage
Prise de décision rapide : Identification immédiate des tendances
Communication efficace : Partage d’insights de manière convaincante
2.3. Principes de design
2.3.1. Principes fondamentaux
Clarté : Un bon graphique doit être immédiatement compréhensible
Simplicité : Éviter la surcharge d’information
Honnêteté : Ne pas déformer les données (échelles appropriées, axes corrects)
Esthétique : Un graphique agréable retient l’attention et facilite la lecture
2.3.2. Choix du type de graphique
Objectif |
Type de données |
Graphique recommandé |
|---|---|---|
Montrer une distribution |
1 variable continue |
Histogramme, Density plot, Boxplot |
Comparer des catégories |
1 catégorielle + 1 continue |
Bar plot, Boxplot par groupe |
Montrer une relation |
2 variables continues |
Scatter plot, Regression plot |
Montrer une évolution |
Temps + variable continue |
Line plot, Area plot |
Montrer une composition |
Catégories avec proportions |
Pie chart, Stacked bar |
Montrer des corrélations |
Plusieurs variables continues |
Heatmap, Pair plot |
2.3.3. Bonnes et mauvaises pratiques
Bonnes pratiques :
Toujours inclure un titre descriptif
Étiqueter clairement les axes
Utiliser une légende si nécessaire
Choisir des couleurs appropriées (daltonisme)
Commencer l’axe Y à zéro pour les barres
À éviter :
Graphiques 3D inutiles
Trop de couleurs ou effets
Échelles trompeuses
Légendes illisibles
Surcharge d’information
2.4. Bibliothèques de visualisation
2.4.1. Python
Matplotlib : Bibliothèque de base, contrôle total
import matplotlib.pyplot as plt
# Configuration de base
plt.figure(figsize=(10, 6))
plt.style.use('seaborn') # Style prédéfini
Seaborn : Interface de haut niveau, graphiques statistiques
import seaborn as sns
# Configuration du style
sns.set_style("whitegrid")
sns.set_palette("husl")
Plotly : Graphiques interactifs
import plotly.express as px
import plotly.graph_objects as go
2.4.2. R
ggplot2 : Grammaire des graphiques
library(ggplot2)
# Thème personnalisé
theme_set(theme_minimal())
Base R : Graphiques simples et rapides
# Configuration globale
par(mfrow = c(2, 2)) # Grille 2x2
2.5. Types de graphiques essentiels
2.5.1. Histogrammes et distributions
Histogramme : Distribution d’une variable continue
# Python - Matplotlib
plt.figure(figsize=(10, 6))
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.xlabel('Valeur')
plt.ylabel('Fréquence')
plt.title('Distribution des valeurs')
plt.show()
# Python - Seaborn (avec KDE)
plt.figure(figsize=(10, 6))
sns.histplot(data=df, x='column', kde=True, bins=30)
plt.title('Distribution avec courbe de densité')
plt.show()
# R - ggplot2
ggplot(df, aes(x = column)) +
geom_histogram(bins = 30, fill = "steelblue",
color = "black", alpha = 0.7) +
labs(title = "Distribution des valeurs",
x = "Valeur", y = "Fréquence") +
theme_minimal()
# Avec courbe de densité
ggplot(df, aes(x = column)) +
geom_histogram(aes(y = ..density..), bins = 30,
fill = "steelblue", alpha = 0.5) +
geom_density(color = "red", size = 1) +
theme_minimal()
Boxplot : Résumé de la distribution avec quartiles
# Python - Seaborn
plt.figure(figsize=(10, 6))
sns.boxplot(data=df, x='categorie', y='valeur')
plt.title('Distribution par catégorie')
plt.xticks(rotation=45)
plt.show()
# Violin plot (distribution + boxplot)
plt.figure(figsize=(10, 6))
sns.violinplot(data=df, x='categorie', y='valeur')
plt.show()
# R - ggplot2
ggplot(df, aes(x = categorie, y = valeur)) +
geom_boxplot(fill = "lightblue") +
labs(title = "Distribution par catégorie") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
# Violin plot
ggplot(df, aes(x = categorie, y = valeur)) +
geom_violin(fill = "lightblue") +
geom_boxplot(width = 0.1) +
theme_minimal()
2.5.2. Graphiques de relation
Scatter plot : Relation entre deux variables continues
# Python - Matplotlib
plt.figure(figsize=(10, 6))
plt.scatter(df['x'], df['y'], alpha=0.6)
plt.xlabel('Variable X')
plt.ylabel('Variable Y')
plt.title('Relation entre X et Y')
plt.show()
# Python - Seaborn avec régression
plt.figure(figsize=(10, 6))
sns.scatterplot(data=df, x='x', y='y', hue='categorie')
sns.regplot(data=df, x='x', y='y', scatter=False, color='red')
plt.title('Relation avec ligne de régression')
plt.show()
# R - ggplot2
ggplot(df, aes(x = x, y = y)) +
geom_point(alpha = 0.6) +
labs(title = "Relation entre X et Y",
x = "Variable X", y = "Variable Y") +
theme_minimal()
# Avec régression et catégories
ggplot(df, aes(x = x, y = y, color = categorie)) +
geom_point(alpha = 0.6, size = 3) +
geom_smooth(method = "lm", se = TRUE) +
labs(title = "Relation avec régression") +
theme_minimal()
Line plot : Évolution temporelle
# Python - Matplotlib
plt.figure(figsize=(12, 6))
plt.plot(df['date'], df['valeur'], marker='o', linestyle='-')
plt.xlabel('Date')
plt.ylabel('Valeur')
plt.title('Évolution temporelle')
plt.xticks(rotation=45)
plt.grid(True, alpha=0.3)
plt.show()
# Python - Seaborn (plusieurs séries)
plt.figure(figsize=(12, 6))
sns.lineplot(data=df, x='date', y='valeur', hue='categorie')
plt.title('Évolution par catégorie')
plt.show()
# R - ggplot2
ggplot(df, aes(x = date, y = valeur)) +
geom_line(color = "steelblue", size = 1) +
geom_point(color = "steelblue", size = 2) +
labs(title = "Évolution temporelle",
x = "Date", y = "Valeur") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
# Plusieurs séries
ggplot(df, aes(x = date, y = valeur, color = categorie)) +
geom_line(size = 1) +
geom_point(size = 2) +
labs(title = "Évolution par catégorie") +
theme_minimal()
2.5.3. Graphiques de comparaison
Bar plot : Comparaison de catégories
# Python - Matplotlib
plt.figure(figsize=(10, 6))
plt.bar(df['categorie'], df['valeur'], color='steelblue', edgecolor='black')
plt.xlabel('Catégorie')
plt.ylabel('Valeur')
plt.title('Comparaison par catégorie')
plt.xticks(rotation=45)
plt.show()
# Python - Seaborn (avec erreurs)
plt.figure(figsize=(10, 6))
sns.barplot(data=df, x='categorie', y='valeur', ci=95)
plt.title('Moyennes avec intervalles de confiance')
plt.show()
# Barres groupées
plt.figure(figsize=(12, 6))
sns.barplot(data=df, x='mois', y='valeur', hue='annee')
plt.title('Comparaison par mois et année')
plt.show()
# R - ggplot2
ggplot(df, aes(x = categorie, y = valeur)) +
geom_bar(stat = "identity", fill = "steelblue",
color = "black") +
labs(title = "Comparaison par catégorie",
x = "Catégorie", y = "Valeur") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
# Barres groupées
ggplot(df, aes(x = mois, y = valeur, fill = annee)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Comparaison par mois et année") +
theme_minimal()
# Barres empilées
ggplot(df, aes(x = categorie, y = valeur, fill = type)) +
geom_bar(stat = "identity", position = "stack") +
labs(title = "Composition par catégorie") +
theme_minimal()
2.5.4. Heatmaps et corrélations
Heatmap : Visualisation de matrices
# Python - Seaborn
# Matrice de corrélation
corr_matrix = df.corr()
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, fmt='.2f',
cmap='coolwarm', center=0,
square=True, linewidths=1)
plt.title('Matrice de corrélation')
plt.show()
# Heatmap de données
pivot_table = df.pivot_table(values='valeur',
index='ligne',
columns='colonne')
plt.figure(figsize=(12, 8))
sns.heatmap(pivot_table, annot=True, fmt='.0f',
cmap='YlOrRd')
plt.title('Heatmap des valeurs')
plt.show()
# R - ggplot2
library(reshape2)
# Matrice de corrélation
corr_matrix <- cor(df[, numeric_columns])
corr_melted <- melt(corr_matrix)
ggplot(corr_melted, aes(x = Var1, y = Var2, fill = value)) +
geom_tile() +
geom_text(aes(label = round(value, 2))) +
scale_fill_gradient2(low = "blue", high = "red",
mid = "white", midpoint = 0) +
labs(title = "Matrice de corrélation") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Pair plot : Matrice de scatter plots
# Python - Seaborn
sns.pairplot(df[['var1', 'var2', 'var3', 'categorie']],
hue='categorie',
diag_kind='kde')
plt.suptitle('Matrice de relations', y=1.02)
plt.show()
# R - GGally
library(GGally)
ggpairs(df[, c('var1', 'var2', 'var3', 'categorie')],
aes(color = categorie),
upper = list(continuous = "points"),
lower = list(continuous = "smooth"),
diag = list(continuous = "densityDiag"))
2.6. Visualisations avancées
2.6.1. Graphiques multiples (Subplots)
# Python - Matplotlib
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# Graphique 1
axes[0, 0].hist(df['var1'], bins=30)
axes[0, 0].set_title('Distribution Var1')
# Graphique 2
axes[0, 1].scatter(df['x'], df['y'])
axes[0, 1].set_title('Relation X-Y')
# Graphique 3
axes[1, 0].bar(categories, values)
axes[1, 0].set_title('Comparaison')
# Graphique 4
axes[1, 1].plot(dates, values)
axes[1, 1].set_title('Évolution')
plt.tight_layout()
plt.show()
# R - ggplot2 avec patchwork
library(patchwork)
p1 <- ggplot(df, aes(x = var1)) +
geom_histogram(bins = 30) +
ggtitle("Distribution Var1")
p2 <- ggplot(df, aes(x = x, y = y)) +
geom_point() +
ggtitle("Relation X-Y")
p3 <- ggplot(df, aes(x = categorie, y = valeur)) +
geom_bar(stat = "identity") +
ggtitle("Comparaison")
p4 <- ggplot(df, aes(x = date, y = valeur)) +
geom_line() +
ggtitle("Évolution")
# Combinaison
(p1 + p2) / (p3 + p4)
2.6.2. Graphiques interactifs
Python - Plotly :
import plotly.express as px
# Scatter interactif
fig = px.scatter(df, x='x', y='y',
color='categorie',
size='taille',
hover_data=['info1', 'info2'],
title='Graphique interactif')
fig.show()
# Line plot interactif avec rangeslider
fig = px.line(df, x='date', y='valeur',
title='Évolution avec sélecteur de plage')
fig.update_xaxes(rangeslider_visible=True)
fig.show()
# 3D scatter
fig = px.scatter_3d(df, x='x', y='y', z='z',
color='categorie')
fig.show()
R - Plotly :
library(plotly)
# Scatter interactif
p <- plot_ly(df, x = ~x, y = ~y,
color = ~categorie,
size = ~taille,
text = ~paste("Info:", info),
type = 'scatter', mode = 'markers')
p <- p %>% layout(title = "Graphique interactif")
p
# ggplot2 vers plotly
p_gg <- ggplot(df, aes(x = x, y = y, color = categorie)) +
geom_point() +
labs(title = "Conversion ggplot vers plotly")
ggplotly(p_gg)
2.7. Personnalisation avancée
2.7.1. Thèmes et styles
Python :
# Matplotlib - Style personnalisé
plt.style.use('seaborn-darkgrid')
# ou définir manuellement
plt.rcParams['figure.figsize'] = [12, 8]
plt.rcParams['font.size'] = 12
plt.rcParams['lines.linewidth'] = 2
plt.rcParams['axes.grid'] = True
# Seaborn - Thème personnalisé
sns.set_theme(style="whitegrid",
palette="husl",
font_scale=1.2,
rc={'figure.figsize': (12, 8)})
R :
# ggplot2 - Thème personnalisé
theme_custom <- theme_minimal() +
theme(
text = element_text(size = 12),
plot.title = element_text(size = 16, face = "bold"),
axis.title = element_text(size = 14),
axis.text = element_text(size = 12),
legend.position = "bottom",
panel.grid.minor = element_blank(),
plot.background = element_rect(fill = "white"),
plot.margin = margin(1, 1, 1, 1, "cm")
)
# Appliquer globalement
theme_set(theme_custom)
2.7.2. Couleurs
Palettes de couleurs :
# Python - Matplotlib
colors = plt.cm.Set3(np.linspace(0, 1, n_colors))
# Python - Seaborn
palette = sns.color_palette("husl", n_colors)
sns.set_palette(palette)
# Palettes personnalisées
custom_colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4']
# R - ggplot2
# Palettes prédéfinies
scale_fill_brewer(palette = "Set3")
scale_color_viridis_d()
# Palette personnalisée
custom_colors <- c("#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4")
scale_fill_manual(values = custom_colors)
2.7.3. Annotations
# Python
plt.figure(figsize=(10, 6))
plt.plot(x, y)
# Texte
plt.text(x_pos, y_pos, 'Annotation', fontsize=12, ha='center')
# Flèche
plt.annotate('Point important', xy=(x1, y1), xytext=(x2, y2),
arrowprops=dict(arrowstyle='->', color='red'))
# Ligne verticale/horizontale
plt.axvline(x=5, color='red', linestyle='--', alpha=0.5)
plt.axhline(y=10, color='blue', linestyle='--', alpha=0.5)
# Zone colorée
plt.axvspan(2, 4, alpha=0.3, color='yellow')
# R - ggplot2
ggplot(df, aes(x = x, y = y)) +
geom_line() +
# Texte
annotate("text", x = x_pos, y = y_pos,
label = "Annotation", size = 5) +
# Flèche
annotate("segment", x = x1, xend = x2,
y = y1, yend = y2,
arrow = arrow(length = unit(0.3, "cm"))) +
# Lignes de référence
geom_vline(xintercept = 5, color = "red",
linetype = "dashed", alpha = 0.5) +
geom_hline(yintercept = 10, color = "blue",
linetype = "dashed", alpha = 0.5) +
# Zone colorée
annotate("rect", xmin = 2, xmax = 4,
ymin = -Inf, ymax = Inf,
alpha = 0.3, fill = "yellow")
2.8. Export et sauvegarde
# Python
# Matplotlib
plt.savefig('graphique.png', dpi=300, bbox_inches='tight')
plt.savefig('graphique.pdf', format='pdf')
plt.savefig('graphique.svg', format='svg')
# Seaborn (utilise matplotlib)
fig = sns_plot.get_figure()
fig.savefig('output.png', dpi=300)
# Plotly
fig.write_image("fig.png", width=1200, height=800)
fig.write_html("fig.html")
# R - ggplot2
ggsave("graphique.png", plot = p,
width = 10, height = 6, dpi = 300)
ggsave("graphique.pdf", plot = p,
width = 10, height = 6)
# Base R
png("graphique.png", width = 800, height = 600)
plot(x, y)
dev.off()
# Plotly
library(htmlwidgets)
saveWidget(p, "graphique.html")
2.9. Conclusion
Ce chapitre a couvert les aspects essentiels de la visualisation de données :
Principes de design et choix approprié des graphiques
Types de graphiques fondamentaux (distributions, relations, comparaisons)
Techniques de personnalisation et d’annotation
Graphiques interactifs pour l’exploration
Export et partage des visualisations
La maîtrise de ces techniques permet de : - Explorer efficacement les données - Identifier des patterns et anomalies - Communiquer des insights de manière claire - Créer des rapports professionnels
Ces compétences seront essentielles pour le chapitre suivant sur les applications web interactives.