3.2 Principaux graphiques
Puisque vous avez désormais une certaine connaissance des bases de la grammaire des graphiques implémentées par ggplot2
, vous apprendrez dans les sous-sections suivantes à construire les principaux graphiques que vous utiliserez régulièrement ou que vous présenterez dans un article scientifique.
3.2.1 Histogramme
L’histogramme permet de décrire graphiquement la forme de la distribution d’une variable. Pour le réaliser, nous utilisons la fonction geom_histogram
. Le paramètre le plus important est le nombre de barres (bins
) qui composent l’histogramme. Plus ce nombre est grand, plus l’histogramme est précis et, à l’inverse, plus il est petit, plus l’histogramme est simplifié. En revanche, il faut éviter d’utiliser un nombre de barres trop élevé comparativement au nombre d’observations disponibles dans le jeu de données, sinon l’histogramme risque d’avoir plein de trous.
3.2.1.1 Histogramme simple
Générons quatre variables ayant respectivement une distribution gaussienne, Student, Gamma et bêta, puis réalisons un histogramme pour chacune de ces variables et combinons-les avec la fonction ggarrange
(figure 3.21).
<- data.frame(
distribs gaussien = rnorm(1000, mean = 5, sd = 1.5),
gamma = rgamma(1000, shape = 2, rate = 12),
beta = rbeta(1000,shape1 = 5, shape2 = 1, ncp = 2),
student = rt(1000,ncp = 20, df = 5)
)
<- ggplot(data = distribs) +
plot1 geom_histogram(aes(x = gaussien), bins = 50, color = "#343a40", fill = "#e63946")+
labs(y="fréquences")+ylim(c(0,130))
<- ggplot(data = distribs) +
plot2 geom_histogram(aes(x = gamma), bins = 50, color = "#343a40", fill = "#f1faee")+
labs(y="fréquences")+ylim(c(0,130))
<- ggplot(data = distribs) +
plot3 geom_histogram(aes(x = beta), bins = 50, color = "#343a40", fill = "#a8dadc")+
labs(y="fréquences")+ylim(c(0,130))
<- ggplot(data = distribs) +
plot4 geom_histogram(aes(x = student), bins = 50, color = "#343a40", fill = "#1d3557")+
labs(y="fréquences")+ylim(c(0,130))
<- list(plot1, plot2, plot3, plot4)
histogrammes
ggarrange(plotlist = histogrammes, ncol = 2, nrow = 2)
Notez que cette syntaxe est très lourde. Dans le cas présent, il serait plus judicieux d’utiliser la fonction facet_wrap
. Pour cela, nous devons au préalable empiler nos données, ce qui signifie changer la forme du DataFrame actuel, qui comprend quatre colonnes (gaussien, Gamma, bêta et student) et 1000 observations, pour qu’il n’ait plus que deux colonnes (la valeur originale et le nom de l’ancienne colonne) et 4000 observations. La figure 3.22 décrit graphiquement ce processus qui peut être effectué avec la fonction melt
du package reshape2
.
library(reshape2)
#faire fondre le jeu de données
<- melt(distribs, measure.vars = c("gaussien", "gamma",
melted_distribs "beta","student"))
#renommer les colonnes du nouveau DataFrame
names(melted_distribs) <- c("distribution", "valeur")
#convertir la variable catégorielle en facteur
$distribution <- as.factor(melted_distribs$distribution)
melted_distribs
ggplot(data = melted_distribs)+
geom_histogram(aes(x = valeur, fill = distribution), bins = 50, color = "#343a40") +
ylim(c(0,130)) +
labs(x = "valeur",
y = "fréquences")+
scale_fill_manual(values = c("#e63946","#f1faee","#a8dadc","#1d3557"))+
facet_wrap(vars(distribution), ncol=2, scales = "free")+
theme(legend.position = "none")
3.2.1.2 Histogramme de densité
Les histogrammes que nous venons de construire utilisent la fréquence des observations pour délimiter la hauteur des barres. Il est possible de changer ce comportement pour plutôt utiliser la densité. L’intérêt est notamment de se rapprocher encore de la définition d’une distribution puisqu’avec cette configuration, la somme totale de la surface de l’histogramme est égale à 1. La hauteur de chaque barre représente alors la probabilité d’obtenir l’étendue de valeurs représentées par cette barre. Prenons pour exemple la variable avec la distribution normale que nous venons de voir.
<- ggplot(data = distribs) +
plot1 geom_histogram(aes(x = gaussien, y = ..density..),
bins = 30, color = "#343a40", fill = "#1d3557")+
labs(x = "gaussien", y = "densité")
<- ggplot(data = distribs) +
plot2 geom_histogram(aes(x = gaussien, y = ..count..),
bins = 30, color = "#343a40", fill = "#a8dadc")+
labs(x = "gaussien", y = "fréquences")
ggarrange(plotlist = list(plot1, plot2), ncol = 2)
Le graphique de droite (fréquence) nous indique donc que plus de 60 observations ont une valeur d’environ 5 (entre 4,76 et 5,34, compte tenu de la largeur de la barre), ce qui se traduit par une probabilité de presque 30 % d’obtenir cette valeur en tirant une observation au hasard dans le jeu de données.
3.2.1.3 Histogramme avec courbe de distribution
Les histogrammes sont souvent utilisés pour vérifier graphiquement si une distribution empirique s’approche d’une courbe normale. Pour cela, nous ajoutons sur l’histogramme de la variable empirique la forme qu’aurait une distribution normale parfaite en utilisant la moyenne et l’écart type de la distribution empirique. Pour créer cette figure dans ggplot2
, il suffit d’utiliser la fonction stat_function
pour créer un nouveau calque. Il est aussi possible d’ajouter une ligne verticale (geom_vline
) pour indiquer la moyenne de la distribution.
<- mean(distribs$gaussien)
moyenne <- sd(distribs$gaussien)
ecart_type
ggplot(data = distribs) +
geom_histogram(aes(x = gaussien, y = ..density..),
bins = 30, color = "#343a40", fill = "#a8dadc") +
labs(x = "gaussien",
y = "densité")+
stat_function(fun = dnorm, args = list(mean = moyenne, sd = ecart_type),
color = "#e63946", size = 1.2, linetype = "dashed") +
geom_vline(xintercept = moyenne, color = 'red', size = 1)+
annotate("text", x = round(moyenne,2)+0.5, y = 0.31, hjust = 'left',
label = paste('moyenne : ',round(moyenne,2),sep=''))
Dans notre cas, nous savons que notre variable est normalement distribuée (car produite avec la fonction rnorm
), et nous pouvons constater la grande proximité entre l’histogramme et la courbe normale.
3.2.1.4 Histogramme avec coloration des valeurs extrêmes
Il peut être nécessaire d’attirer le regard sur certaines parties de l’histogramme, comme sur des valeurs extrêmes. Si nous reprenons notre distribution de Student, nous pouvons clairement distinguer un ensemble de valeurs fortes à droite de la distribution. Nous pourrions, dans notre cas, considérer que des valeurs au-delà de 50 constituent des cas extrêmes que nous souhaitons représenter dans une autre couleur. Pour cela, nous devons créer une variable catégorielle nous permettant de distinguer ces cas particuliers.
$cas_extreme <- ifelse(distribs$student >=50, "extrême", "normale")
distribs
ggplot(data = distribs) +
geom_histogram(aes(x = student, y = ..count.., fill = cas_extreme),
bins = 30, color = "#343a40")+
scale_fill_manual("", values = c("#a8dadc","#e63946"))+
labs(title = 'Distribution de Student',x = "valeur", y = "fréquence")
3.2.2 Graphique de densité
L’histogramme est utilisé pour approximer graphiquement la distribution d’une variable. Sa principale limite est de représenter la variable de façon discontinue. Une option intéressante est d’utiliser une version lissée de l’histogramme, soit le graphique de densité. Cette opération de lissage est réalisée le plus souvent à partir de fonctions kernel. Reconstruisons notre figure avec les quatre distributions, mais en utilisant cette fois-ci des graphiques de densité.
ggplot(data = melted_distribs)+
geom_density(aes(x = valeur, fill = distribution), color = "#343a40") +
scale_fill_manual(values = c("#e63946","#f1faee","#a8dadc","#1d3557"))+
facet_wrap(vars(distribution), ncol=2, scales = "free")+
theme(legend.position = "none")
Les graphiques de densité sont souvent utilisés pour comparer la distribution d’une variable pour plusieurs sous-groupes d’une population. Si nous reprenons le jeu de données iris, nous pouvons comparer les longueurs de sépales en fonction des espèces. Nous constatons ainsi que les setosas ont une nette tendance à avoir des sépales plus courts et qu’à l’inverse, les virginicas ont les sépales généralement les plus longs.
ggplot(data = iris)+
geom_density(aes(x = Sepal.Length, fill = Species),
color = "#343a40", alpha = 0.4)+
labs(x = 'Longueur de sépales',
y = '',
fill = 'Espèce')
3.2.3 Nuage de points
Un nuage de points est un outil très intéressant pour visualiser la relation existante entre deux variables. Prenons un exemple concret et analysons le volume de CO2 produit annuellement par habitant en comparaison avec le niveau d’urbanisation dans l’ensemble des pays à travers le monde. Nous avons extrait ces données sur le site web de la Banque mondiale, puis nous les avons structurés dans un fichier csv.
<- read.csv("data/graphique/world_urb_co2.csv", encoding = "UTF-8")
data_co2 names(data_co2)
## [1] "country_code" "year" "Population" "Urbanisation" "CO2_kt" "Country.Name"
## [7] "CO2t_hab" "region7" "region23"
3.2.3.1 Nuage de points simple
Commençons par un nuage de points simple avec l’ensemble des données.
ggplot(data = data_co2)+
geom_point(aes(x = Urbanisation, y = CO2t_hab))+
labs(x = "Niveau d'urbanisation (%)",
y = 'Tonnes de CO2 annuelle / habitant',
title = 'Relation entre urbanisation et production de CO2 par habitant')
À la première lecture de ce graphique, nous observons immédiatement un ensemble de points étranges dont le volume de CO2 par habitant annuel est au-dessus de 150 tonnes et dont le niveau d’urbanisation est proche de 50 %. Isolons ces données pour observer de quoi il s’agit.
<- subset(data_co2, data_co2$CO2t_hab >= 150)
cas_etrange print(cas_etrange$Country.Name)
## [1] "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba"
## [13] "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba" "Aruba"
## [25] "Aruba"
Il s’agit d’une petite île néerlandaise des Caraïbes nommée Aruba disposant d’une faible population, mais avec des activités très polluantes (raffinerie et extraction d’or). Nous faisons ici le choix de retirer ces observations puisqu’elles sont assez peu représentatives de la tendance mondiale. Cette démarche si simple relève ainsi de l’analyse exploratoire des données! Sans ce graphique, nous n’aurions probablement jamais identifié ces cas problématiques.
<- subset(data_co2, data_co2$CO2t_hab <= 150) data_co2
Reconstruisons le nuage de points maintenant que ces données aberrantes ont été retirées.
<- ggplot(data = data_co2)+
graphique geom_point(aes(x = Urbanisation, y = CO2t_hab))+
labs(x = "Niveau d'urbanisation (%)",
y = 'Tonnes de CO2 annuelle / habitant',
title = 'Relation entre urbanisation et production de CO2 par habitant')
Voilà qui est mieux! Cependant, le grand nombre de points restant rend la lecture du graphique assez difficile puisqu’ils se superposent. Une première option à envisager, dans ce cas, est à la fois d’ajouter de la transparence aux points et de réduire leur taille :
ggplot(data = data_co2)+
geom_point(aes(x = Urbanisation, y = CO2t_hab), alpha = 0.2, size = 0.5)+
labs(x = "Niveau d'urbanisation (%)",
y = 'Tonnes de CO2 annuelle / habitant',
title = 'Relation entre urbanisation et production de CO2 par habitant')
3.2.3.2 Nuage de points avec densité
Bien que la transparence nous aide un peu à distinguer les secteurs du graphique avec le plus de points, il serait plus efficace d’abandonner la géométrie des points pour la remplacer par une géométrie de densité en deux dimensions. Une première approche consiste à diviser l’espace du graphique en petits carrés et à compter le nombre de points tombant dans chaque carré (en somme, un histogramme en deux dimensions).
ggplot(data = data_co2)+
geom_bin2d(aes(x = Urbanisation, y = CO2t_hab), bins = 50) +
scale_fill_continuous(type = "viridis") +
labs(x = "Niveau d'urbanisation (%)",
y = 'Tonnes de CO2 annuelle / habitant',
fill = "Effectif",
title = 'Relation entre urbanisation et production de CO2 par habitant')
Nous observons ainsi une forte concentration dans le bas du graphique; les pays avec des rejets annuels de CO2 supérieurs à 15 tonnes par habitant sont relativement rares. Pour les personnes préférant les représentations plus élaborées, il est aussi possible de diviser l’espace du graphique avec des hexagones en utilisant le package hexbin
.
ggplot(data = data_co2)+
geom_hex(aes(x = Urbanisation, y = CO2t_hab), bins = 50) +
scale_fill_continuous(type = "viridis") +
labs(x = "Niveau d'urbanisation (%)",
y = 'Tonnes de CO2 annuelle / habitant',
fill = "Effectif",
title = 'Relation entre urbanisation et production de CO2 par habitant')
Enfin, il est aussi possible de réaliser une version lissée de ces graphiques avec une fonction kernel en deux dimensions (stat_density_2d
) :
ggplot(data = data_co2)+
stat_density_2d(aes(x = Urbanisation, y = CO2t_hab, fill = ..density..),
geom = "raster", n = 50, contour = FALSE) +
scale_fill_continuous(type = "viridis") +
labs(x = "Niveau d'urbanisation (%)",
y = 'Tonnes de CO2 annuelle / habitant',
fill = "densité",
title = 'Relation entre urbanisation et production de CO2 par habitant')+
ylim(0,25)
3.2.3.3 Nuage de points et droite de régression
Afin de faire ressortir une éventuelle relation entre les variables représentées sur les deux axes, il est possible d’afficher la droite de régression sur le graphique entre X et Y. Cette opération s’effectue avec la fonction geom_smooth
.
<- ggplot(data = data_co2)+
graphique geom_point(aes(x = Urbanisation, y = CO2t_hab), alpha = 0.2, size = 0.5)+
geom_smooth(aes(x = Urbanisation, y = CO2t_hab), method = lm, color = "red")+
labs(x = "Niveau d'urbanisation (%)",
y = 'Tonnes de CO2 annuelle / habitant',
title = 'Relation entre urbanisation et production de CO2 par habitant')
Notez que l’argument method = lm
permet d’indiquer que nous souhaitons utiliser une régression linéaire (linear model) pour tracer la géométrie (une droite de régression). La droite semble bien indiquer une relation positive entre les deux variables : une augmentation de l’urbanisation serait associée à une augmentation de la production annuelle de CO2 par habitant. Nous pourrions également vérifier si une relation non linéaire serait plus adaptée au jeu de données. Dans notre cas, une relation quadratique pourrait produire un meilleur ajustement.
ggplot(data = data_co2)+
geom_point(aes(x = Urbanisation, y = CO2t_hab), alpha = 0.2, size = 0.7)+
geom_smooth(aes(x = Urbanisation, y = CO2t_hab), method = lm,
color = "red", formula = y ~ I(x**2))+
labs(x = "Niveau d'urbanisation (%)",
y = 'Tonnes de CO2 annuelle / habitant',
title = 'Relation entre urbanisation et production de CO2 par habitant')
La régression quadratique (avec x au carré) nous indique ainsi que l’impact du niveau d’urbanisation est plus important à mesure que ce niveau augmente. Vous pouvez également constater que la courbe ne prédit pas de valeurs négatives comparativement à la droite précédente. Il est également possible d’ajuster une courbe sans choisir au préalable sa forme (dans le cas précédent \(x^2\)) en utilisant une méthode d’ajustement local appelée loess.
<- ggplot(data = data_co2)+
graphique geom_point(aes(x = Urbanisation, y = CO2t_hab), alpha = 0.2, size = 0.5)+
geom_smooth(aes(x = Urbanisation, y = CO2t_hab), method = loess,
color = "red")+
labs(x = "Niveau d'urbanisation (%)",
y = 'Tonnes de CO2 annuelle / habitant',
title = 'Relation entre urbanisation et production de CO2 par habitant')
La relation non linéaire révèle davantage d’informations : l’augmentation de l’urbanisation est associée à une augmentation de l’émission de CO2 par habitant uniquement jusqu’à 75 % d’urbanisation; au-delà de ce seuil, la relation ne tient plus. Ces résultats semblent cohérents avec l’évolution classique de l’économie d’un pays passant progressivement d’une économie agricole, à une économie industrialisée et finalement une économie de services.
3.2.4 Graphique en ligne
Un graphique en ligne permet de représenter l’évolution d’une variable, généralement dans le temps. Dans le jeu de données précédent, nous disposons des émissions de CO2 par habitant de nombreux pays sur plusieurs années. Nous pouvons ainsi représenter l’évolution des émissions pour chaque pays avec un graphique en ligne. Pour éviter de le surcharger, cet exercice est réalisé uniquement sur les pays de l’Europe de l’Ouest.
# conversion de la variable year textuelle en variable numérique
$an <- as.numeric(data_co2$year)
data_co2# extraction des données d'Europe de l'Ouest
<- subset(data_co2, data_co2$region23 == "Europe de l'Ouest")
data_europe # choix des valeurs pour l'axe des x
<- seq(1960,2020,10)
x_ticks
ggplot(data = data_europe)+
geom_path(aes(x = an, y = CO2t_hab, color = Country.Name))+
labs(x = "Années",
y = 'Tonnes de CO2 annuelle / habitant',
color = "Pays",
title = 'Évolution de la production de CO2 par habitant') +
scale_x_continuous(breaks = x_ticks, labels = x_ticks)+
theme_tufte()
Nous remarquons notamment qu’aucune donnée, avant 2005, n’est disponible pour le Liechtenstein.
3.2.4.1 Barre d’erreur et en bande
Sur un graphique, il est souvent pertinent de représenter l’incertitude que nous avons sur nos données. Cela peut être fait à l’aide de barres d’erreur ou à l’aide de polygones délimitant les marges d’incertitude. En guise d’exemple, admettons que les données précédentes sont fiables à plus ou moins 10 %. En d’autres termes, la valeur d’émission de CO2 annuelle serait relativement incertaine et pourrait se situer dans un intervalle de 10 % autour de la valeur fournie par la Banque mondiale. Nous obtenons ainsi une borne inférieure (valeur donnée - 10 %) et une borne supérieure (valeur donnée + 10 %). Nous pouvons facilement calculer ces bornes et les faire apparaître dans notre graphique précédent.
$borne_basse <- data_europe$CO2t_hab - 0.1 * data_europe$CO2t_hab
data_europe$borne_haute <- data_europe$CO2t_hab + 0.1 * data_europe$CO2t_hab
data_europe
ggplot(data = data_europe)+
geom_point(aes(x = an, y = CO2t_hab, color = Country.Name), size = 0.7)+
geom_errorbar(aes(x = an, ymin = borne_basse, ymax = borne_haute, color = Country.Name))+
labs(x = "Années",
y = 'Tonnes de CO2 annuelle / habitant',
color = "Pays",
title = 'Évolution de la production de CO2 par habitant') +
scale_x_continuous(breaks = x_ticks, labels = x_ticks)+
theme_tufte()
Ces barres d’erreurs indiquent notamment qu’il n’y a finalement aucun écart significatif entre la Belgique, les Pays-Bas et l’Allemagne à partir des années 1990. Une autre option de représentation est d’utiliser des polygones avec la fonction geom_ribbon
.
ggplot(data = data_europe)+
geom_path(aes(x = an, y = CO2t_hab, color = Country.Name), size = 0.7)+
geom_ribbon(aes(x = an, ymin = borne_basse, ymax = borne_haute,
fill = Country.Name), alpha = 0.4)+
labs(x = "Années",
y = 'Tonnes de CO2 annuelle / habitant',
color = "Pays",
title = 'Évolution de la production de CO2 par habitant') +
scale_x_continuous(breaks = x_ticks, labels = x_ticks)+
theme_tufte()+
guides( fill = FALSE)
## Warning: The `<scale>` argument of `guides()` cannot be `FALSE`. Use "none" instead as of ggplot2
## 3.3.4.
Le message du graphique est le même. Notez que nous avons utilisé ici la fonction guides
pour retirer de la légende les couleurs associées au remplissage des marges d’erreur. Ces couleurs sont les mêmes que celles des lignes et il n’est pas utile de dédoubler la légende. De nombreuses méthodes statistiques produisent des résultats accompagnés d’une mesure de l’incertitude associée à ces résultats. Représenter cette incertitude est crucial pour que le lecteur puisse délimiter la portée des conclusions de vos analyses.
3.2.5 Boîte à moustaches
Les boîtes à moustaches (box plot en anglais) sont des graphiques permettant de comparer les moyennes et les intervalles interquartiles d’une variable continue selon plusieurs groupes d’une population. Si nous reprenons notre exemple précédent, nous pourrions comparer, en fonction de la région du monde, la moyenne de production annuelle de CO2 par habitant. Pour cela, il suffit d’utiliser la fonction geom_boxplot
.
#retirer les observations n'étant pas associées à une région
<- subset(data_co2, is.na(data_co2$region7) == F)
data_co2_comp
ggplot(data = data_co2_comp)+
geom_boxplot(aes(y = region7, x = CO2t_hab))+
labs(x="Tonnes de CO2 par an et habitant", y="Région")
La barre centrale d’une boîte représente la moyenne. Les extrémités de la boîte représentent le premier et le troisième quartile. Plus une boîte est allongée, plus les situations sont diversifiées pour les observations appartenant au groupe représenté par la boîte. Au contraire, une boîte étroite indique un groupe homogène. Notez qu’en inversant les variables dans les axes X et Y, nous obtiendrions des boîtes à moustaches verticales. Cependant, les noms des régions étant assez longs, cela nécessiterait d’avoir un graphique très large. Améliorons quelque peu le rendu de ce graphique en ajoutant des titres.
ggplot(data = data_co2_comp)+
geom_boxplot(aes(y = region7, x = CO2t_hab))+
xlim(c(0,50))+
labs(x = "Tonnes de CO2 par an et habitant",
y = 'Région')
Les points noirs sur le graphique représentent des valeurs extrêmes, soit des observations situées à plus de 1,5 intervalle interquartile d’une extrémité de la boîte. Pour mieux rendre compte de la densité d’observations le long de chaque boîte à moustaches, il est possible de les représenter directement avec la fonction geom_jitter
.
Notez que pour éviter que les valeurs extrêmes identifiées par la fonction geom_boxplot
se superposent avec les points représentant les observations, nous les avons supprimées avec l’argument outlier.shape = NA
.
3.2.6 Graphique en violon
Les boîtes à moustaches donnent des informations pertinentes sur le centre et la dispersion d’une variable en fonction de sous groupes de la population. Cependant, une grande partie de l’information reste masquée par la représentation sous forme de boîte. Une solution est de remplacer la simple boîte par la distribution de la variable étudiée. Nous obtenons ainsi des graphiques en violon (geom_violin
). Considérant les très grands écarts que nous avons observés entre les régions avec les boîtes à moustaches, il est préférable de tracer les graphiques en violon en excluant les régions Afrique Sub-Saharienne et Asie du Sud.
# retirons les observations de régions que nous ne souhaitons par garder
<- subset(data_co2, (! data_co2$region7 %in%
data_co2_comp c("Sub-Saharan Africa", "South Asia"))
& is.na(data_co2$region7)==FALSE)
ggplot(data = data_co2_comp)+
geom_violin(aes(y = region7,x = CO2t_hab))+
xlim(c(0,50))+
labs(x = "Tonnes de CO2 annuelle / habitant",
y = '')+
geom_vline(xintercept = 12, linetype = 'dashed', color = 'blue')
Ces distributions permettent notamment de souligner que deux groupes distincts se retrouvent en Amérique du Nord. L’un dont les émissions annuelles de CO2 par habitant sont inférieures à 12 tonnes (ligne bleue) et l’autre pour lequel elles sont supérieures. En explorant les données, nous constatons que les Bermudes appartiennent au groupe Amérique du Nord, mais ont des niveaux d’émission inférieurs à ceux du Canada et des États-Unis, ce qui explique cette distribution bimodale. Cette information était masquée avec les boîtes à moustaches. Finalement, il est aussi possible de superposer un graphique en violon et une boîte à moustaches pour bénéficier des avantages des deux.
ggplot(data = data_co2_comp)+
geom_violin(aes(y = region7,x = CO2t_hab))+
geom_boxplot(aes(y = region7,x = CO2t_hab), width = 0.15)+
xlim(c(0,50))+
labs(x = "Tonnes de CO2 annuelle / habitant",
y = '')
3.2.7 Graphique en barre
Les graphiques en barre permettent de représenter des quantités (hauteur des barres) réparties dans des catégories (une barre par catégorie). Nous proposons ici un exemple avec des données de déplacements issues de l’Enquête origine-destination 2017 - Région Québec-Lévis, au niveau des grands secteurs. La figure 3.42, tirée du rapport intitulé La mobilité des personnes dans la région de Québec-Lévis (Volet Enquête-ménages : faits saillants) délimite ces grands secteurs.
Nous représentons pour chaque secteur le nombre moyen de déplacements entrant et sortant un jour de semaine en heures de pointe. Les données sont présentées sous forme d’une matrice carrée (avec autant de lignes que de colonnes). L’intersection de la ligne A et de la colonne C indique le nombre de personnes partant du secteur A pour se rendre au secteur C. À l’inverse, l’intersection de la ligne C et de la colonne A indique le nombre de personnes partant du secteur C pour se rendre au secteur A. En sommant les valeurs de chaque ligne, nous obtienons le nombre total de départs par secteur tandis que le nombre d’arrivées est la somme de chaque colonne. Ces opérations peuvent simplement être effectuées avec les fonctions rowSums
et colSums
.
# Chargement des donneées
<- read.csv('data/graphique/Quebec_2017_OD_MJ.csv',
matriceOD header = FALSE, sep = ';') # fichier csv sans entête
# Calcul des sommes en lignes et en colonnes
<- rowSums(matriceOD)
tot_depart <- colSums(matriceOD)
tot_arrivee
# Création d'un DataFrame avec les valeurs et les noms des secteurs
<- data.frame(depart = tot_depart,
df arrivee = tot_arrivee,
secteur = c('Arr. de Beauport (Québec)',
'Arr. de Charlesbourg (Québec)',
'Arr. des Rivières (Québec)',
'Arr. de la Cité-Limoilou (Québec)',
'Arr. de la Haute-Saint-Charles (Québec)',
'Arr. de Sainte-Foy-Sillery-Cap-Rouge (Québec)',
'Arr.de Desjardins (Lévis)',
'Arr. des Chutes–de-la-Chaudière-Est (Lévis)',
'Arr. des Chutes de la Chaudière-Ouest (Lévis)',
'Ceinture Nord',
'Ceinture Sud',
'Hors Territoire'),
code = c('A','B','C','D','E','F','G','H','I','J','K','X'))
# Création des deux graphiques en barre
<- ggplot(data = df)+
plot1 geom_bar(aes(x = code, weight = depart))+
labs(subtitle = 'Départs',
x = 'total',
y = '')
<- ggplot(data = df)+
plot2 geom_bar(aes(x = code, weight = arrivee))+
labs(subtitle = 'Arrivées',
x = 'total',
y = '')
# Stocker les graphiques dans une liste et composer une figure
<- list(plot1, plot2)
list_plot <- ggarrange(plotlist = list_plot, ncol = 1)
tot_plot
# Création d'une légende pour associer le code de chaque secteur
# à son nom. Pour cela nous concaténons en premier les lettres et les noms.
# Nous fusionons ensuite le tout en les séparant par le symbole \n représentant
# un saut de ligne.
<- paste(df$code, df$secteur, sep= ' : ')
nom_secteurs <- paste(nom_secteurs, collapse = '\n')
string_names
<- "Déplacements journaliers moyens en heures de pointe"
titre # Production finale de la figure
annotate_figure(tot_plot,
top = text_grob(titre, face = "bold", size = 11, just = "left"),
right = text_grob(string_names, face = "italic", size = 8,
just = "left", x = 0.05) # position du texte
)
Plutôt que de représenter les arrivées et les départs dans deux graphiques séparés, il est possible de les empiler dans un même graphique en barre. Nous devons au préalable « faire fondre nos données » avec la fonction melt
.
# Faire fondre le jeu de données (empiler les colonnes depart et arrivee)
<- melt(df, id.vars = c('code'), measure.vars = c('depart','arrivee'))
melted_df names(melted_df) <- c('code','deplacement','effectif')
# Ajouter les accents dans la colonne déplacement
$deplacement <- ifelse(melted_df$deplacement == 'depart', 'départs', 'arrivées')
melted_df
# Comparaison du format original et du format "fondu"
head(df)
## depart arrivee secteur code
## V1 49241 34777 Arr. de Beauport (Québec) A
## V2 48909 36344 Arr. de Charlesbourg (Québec) B
## V3 48044 67198 Arr. des Rivières (Québec) C
## V4 63132 108138 Arr. de la Cité-Limoilou (Québec) D
## V5 57367 30859 Arr. de la Haute-Saint-Charles (Québec) E
## V6 86504 112379 Arr. de Sainte-Foy-Sillery-Cap-Rouge (Québec) F
head(melted_df)
## code deplacement effectif
## 1 A départs 49241
## 2 B départs 48909
## 3 C départs 48044
## 4 D départs 63132
## 5 E départs 57367
## 6 F départs 86504
# Réalisation du graphique
<- ggplot(data = melted_df)+
plot1 geom_bar(aes(x = code,weight = effectif, fill = deplacement),color = '#e3e3e3')+
scale_fill_manual(values = c("#e63946","#1d3557"))+
labs(title = titre,
y = 'Effectifs',
x = '',
fill = 'Déplacements')
annotate_figure(plot1,right = text_grob(string_names, face = "italic", size = 7,
just = "left", x = 0.05)) # position du texte)
3.2.8 Graphique circulaire
Une option directe au graphique en barre est le graphique ou diagramme circulaire, appelé aussi graphique en tarte (pour les personnes à la dent sucrée) ou en camembert (pour celles amatrices de fromage). Il est suffissamment connu et utilisé pour qu’aucune présentation ne s’impose. Pour être exact, un graphique en tarte n’est rien d’autre qu’un graphique en barre dont le système de coordonnées a été modifié. Cela impose cependant de calculer à l’avance la position des étiquettes que nous souhaitons ajouter sur le graphique. Reprenons les données de production mondiale de CO2 et calculons les productions totales par région géographique en 2015.
library(dplyr)
# Extraire les données de 2018 pour lesquelles nous connaissons la région
<- subset(data_co2,data_co2$year == "2015" & ! is.na(data_co2$region7))
data_co2_2015
# Effectuer la somme du CO2 par région
<- data_co2_2015 %>%
co2_2015 group_by(region7) %>%
summarise(total_co2 = sum(CO2_kt,na.rm = TRUE))
# Attribuer un code à chaque région pour faciliter la lecture
$code <- c("A","B","C","D","E","F","G")
co2_2015
# Modifier l'ordre des données, calculer les proportions et la position des labels
<- co2_2015 %>%
df arrange(desc(code)) %>%
mutate(prop = total_co2 / sum(co2_2015$total_co2) *100) %>%
mutate(ypos = cumsum(prop)- 0.5*prop )
# Préparer la légende (pourcentages et vrais noms)
<- rev(paste(df$code, " : ", df$region7, "(", round(df$prop,1),"%)"))
nom_region <- paste(nom_region, collapse = '\n')
string_region
# Construire le graphique
<- ggplot(df, aes(x="", y=prop, fill=code)) +
plot1 geom_bar(stat="identity", width=1, color="white") +
coord_polar("y", start=0) +
theme_void() +
theme(legend.position="none") +
geom_text(aes(y = ypos, label = code), color = "white", size=3) +
scale_fill_grey()+
labs(title = "Proportion du CO2 émis en 2015")
# Ajouter la légende
annotate_figure(plot1,right = text_grob(string_region, face = "italic", size = 9,
just = "left", x = 0.05)) # position du texte)
Si à la place de la géométrie geom_bar
, vous utilisez geom_rect
, vous pouvez convertir votre graphique en tarte en graphique en anneau (ou en beigne, pour les personnes à la dent sucrée) :
# Calculer la limite inférieure et supérieure du beigne
$ymax <- cumsum(df$prop)
df$ymin <- c(0, head(df$ymax, n=-1))
df
# Construire le graphique
<- ggplot(df, aes(ymax=ymax, ymin=ymin,
plot1 xmax=4, xmin=3,
y=prop, fill=code)) +
geom_rect(stat="identity", color="white") +
coord_polar("y", start=0) +
theme_void() +
theme(legend.position="none") +
geom_text(aes(x = 3.5,y = ypos, label = code), color = "white", size=3) +
scale_fill_grey()+
xlim(c(2,4))+
labs(title = "Proportion du CO2 émis en 2015")
# Ajouter la légende
annotate_figure(plot1,right = text_grob(string_region, face = "italic", size = 8,
just = "left", x = 0.05)) # position du texte)