Chapitre 4 Introduction à la grammaire des graphiques et à ggplot
Nous avons appris à lire des données, à les manipuler, Nous allons nous intéresser à la manière de les représenter en introduisant le concept de grammaire des graphiques et en appliquant ggplot au traitement des données univariées.
4.1 La grammaire des graphiques
C’est sans doute une des percées conceptuelles la plus intéressante des data sciences. La représentation graphiques des données fait l’objet à la fois d’une explosion créative mais aussi d’une synthèse théorique. C’est l’apport de la grammaire des graphiques.
Ces outils s’appuient sur l’idée de grammaire des graphiques. En voici un clair résumé.En français il y a toujours le larmarange
4.1.1 Un modèle en couche
Celle-ci met un ordre dans les éléments qui composent un graphique et les superpose.

layers
- l’aesthetic definit les éléments que l’on veut représenter : ce qu’on met en abscisse, ce qu’on met en ordonnné, les groupes que l’on veut distinguer.
- la geométrie (geom_x)qui définit la forme de représentation
- les échelles (scale_x)
- Labelisation (labs)
- les templates
- le facetting
ggplot est construit selon cette structure. Voici le book de référence, qui est au centre de ce cours. On aura besoin de manière assez systématique de manipuler les données avant de les représenter, dplyr nous permet de le faire aisément.
4.1.2 Une typologie des représentations
Un point de départ fondamental est la gallery de ggplot,, elle présente de manière synthétique la plupart les types de figures qui peuvent être représentées, avec du code facilement reproductible.
Une classification simple
- Analyse univariée : une seule variable quantitative ou qualitative.
- Analyse bivariée : deux variables quali ou quanti/
- Analyse multivariée
- les variables sont quantitatives : on analyse des matrices de corrélations
- les variables sont qualitatives : on analyse des tableaux croisés
- Analyse temporelles :
- Analyse géospatiale : les chloroplèthes.
- Analyse de réseaux : représenter des noeuds et les arcs qui les relient. Depuis Moreno,
- analyse d’arbres : ils sont des sortes de réseaux mais avec une structure hiérarchiques. le dendogramme est le plus connus.
- Diagramme de flux
4.1.3 L’esthétique
L’art des couleurs tient dans les palettes on aimera celles de Wes Anderson, on peut adorer fishualize
si on a un faible pour les poissons tropicaux.
Pour la théorie voir …
Si l’on est pas créatif on se reportera à des modèles, certains étant fameux. On laisse le lecteur les rechercher ici ou là . A titre d’exemple, une belle leçon, pour reproduire le célèbre BigMac index de The Economist.
## Application à l’analyse univariée
Les données sont extraites de l’ESS, une sélection est disponible ici. Elle couvre les 9 vagues et concernent la France et L’Allemagne. Les variables dépendantes (celles que l’on veut étudier et expliquer) sont les 9 items de la confiance, les variable considérées comme indépendantes (ou explicatives) sont une sélection de variables socio-démographiques : âge, genre, perception du pouvoir d’achat, orientation politique, type d’habitat.
L’analyse univarié, comme son nom l’indique, ne s’intéresse qu’à une seule variable. Celle-ci peut être quantitative ou qualitative et ne comporter qu’un nombre limité de modalités entre lesquels aucune comparaison de grandeur ne peut être faite. Les premières ont le plus souvent dans r un format numérique, les autres correspondent au format factor.
4.1.4 Le cas des variables quantitatives
Les variables quantitatives décrivent une variable dont les valeurs décrivent les quantités d’une grandeur. Elle peuvent être discrètes (dénombrement du d’un nombre d’unités) - le nombre d’habitant), ou continue (le nombre de km parcourus). l’histogramme est l’outil de base pour représenter la distribution d’une telle variable. Il représente pour des intervalles de valeurs donnés, la fréquence des observations.
Sa syntaxe simple comporte d’abord la définition de la variable et de la source de données, puis une des “géométrie” de ggplot : la fonction geom_histogram
. Dans notre exemple, on va représenter le score de confiance institutionnelle pour la France en se concentrant sur la dernière vague d’enquête.
<-readRDS("./data/dfTrust.rds)")
df
#filtrage sur 2018 et la France.
<-df%>%
foofilter(Year=="2018" & cntry=="FR" & !is.na(trust_institut))
# on stocke le diagramme dans l'objet g00,
# pour le réutiliser ultérieurement et pouvoir le compléter.
<-ggplot(foo,aes(x=trust_institut))+
g00geom_histogram()
g00
+labs(title="Distribution de la confiance institutionnelle en France et en 2018",
g00x="Confiance institutionnelle", y="Fréquence")
On va améliorer l’aspect en
- modifiant la couleur et la largeur des barres,
- ajoutant un thème,
- en précisant les éléments textuels (titres, label)
- en calculant et en représentant la valeur moyenne et l’écart-type . Pour ces statistiques, on emploie les fonction de base : mean, sd et round.
On notera que le titre est défini par la concaténation de plusieurs chaines de caractères avec la fonction paste0
. On peut ainsi injecter dans le graphique des éléments externes au jeu de données.
#on calcule la moyenne
=mean(foo$trust_institut, na.rm=TRUE)
moy=sd(foo$trust_institut, na.rm=TRUE)
sd
#avec tous les éléments
<-ggplot(foo,aes(x=trust_institut))+
g01 geom_histogram(binwidth=5,fill="pink")+
labs(title= "Distribution de la confiance institutionnelle",
subtitle= paste0("moyenne = ",round(moy,2), " - écart-type = ", round(sd,2)),
caption="ESS2002-2018",
y= "Fréquence",
x="Confiance (index de 0 à 100)")+
geom_vline(xintercept=moy, color="red",size=1.5)+
geom_segment(y = 0, yend=0,x=moy-sd,xend=moy+sd, color="orange",size=1.5)
g01
On peut souhaiter normaliser un tel graphe et prendre pour convention que la surface soit égale à 1. On représentera donc une fonction de densité de probabilité, à laquelle on peut associer une fonction cumulée de la distribution.
On en profite pour introduire l’usage de cowplot
qui permet d’associer des graphiques en un seul document.
<-ggplot(foo,aes(x=trust_institut))+
g04geom_density(fill="pink2") +
labs(title= "Fonction de densité de probabilité",
caption="ESS2002-2018",
y= "Fréquence",
x="Confiance (index de 1 à 100)")
<-ggplot(foo,aes(x=trust_institut))+
g05stat_ecdf(geom = "step")+
labs(title= "Fonction de distribution empirique cumulée",
caption="ESS2002-2018",
y= "Fréquence",
x="Confiance (index de 1 à 100)")
plot_grid(g04, g05, labels = c('A', 'B'), label_size = 12)
Enfin on peut examiner par rapport à une distribution théorique, en l’occurrence une distribution gaussienne, ou normale, de paramètres égaux à la moyenne et la variance empirique de la distribution. C’est ce que
stat_function
permet de réaliser.
L’ajustement est convenable même si on observe une déviation sur la droite. C’est pourquoi on calcule aussi la Kurtosis et le skewness de la distribution.
#On a déjà calculé la moyenne : mean
#il nous manque l'écart-type et
<-sd(foo$trust_institut, na.rm=TRUE)
sdlibrary(moments)
<-skewness(foo$trust_institut)
sk<-kurtosis(foo$trust_institut)
ks
<-ggplot(foo,aes(x=trust_institut))+
g05labs(title= "Distribution de la confiance institutionnelle", caption="ESS2002-2018",y= "frequence",x="confiance (index de 0 à 100)") +
geom_density(fill="pink2")+
stat_function(fun = dnorm,color="red",size=1.2, args = list(mean =moy, sd=sd))
g05
Un grand classique du test de normalité d’une distribution est le diagramme QQ.
<- ggplot(foo, aes(sample = trust_institut)) +
g06 stat_qq() + stat_qq_line()+
labs(title= "QQplot confiance interpersonnelle",
caption="ESS2002-2018",
y= "Echantillon",x="Théorique")
g06
On finit cette étude détaillée par l’ajustement d’abord d’un modèle (loi normale) aux données. Ensuite d’un modèle de mélange ( Mixture model) par lequel on définit la loi de distribution sous-jascente, comme un mélange entre deux populations normale de paramètres distincts.
https://tinyheero.github.io/2015/10/13/mixture-model.html
<-df %>%
df0na.omit()
#library(MASS)
<-fitdistr(df0$trust_interpersonnel,"normal")
fit<-as.data.frame(fit$estimate)
param<-param[,1]
mean<-param[,1]
sd
<- g05+stat_function(fun = dnorm ,color="orange",size=1.2, args = list( mean=mean, sd=sd))
g07 g07
library(mixtools)
= foo$trust_institut
trust = normalmixEM(trust, k=2) mixmdl
## number of iterations= 237
$mu mixmdl
## [1] 20.77247 50.86798
$sigma mixmdl
## [1] 10.37739 13.51802
$lambda mixmdl
## [1] 0.2034332 0.7965668
plot(mixmdl,which=2)
lines(density(trust), lty=2, lwd=2)
Finalement si notre distribution est univariée, car n’étudiant qu’une variable, on peut quand distinguer deux population distinctes.
4.1.5 D’autres méthodes
Il n’y a pas que l’histogramme ou le diagramme de densité, d’autres méthodes sont utiles, surtout quand on veut comparer des groupes (ce sera l’objet du prochain chapitre). Il s’agit du diagramme à moustache et du diagramme en violon.
<- ggplot(foo, aes(y = trust_institut, x=1)) +
g0306 geom_boxplot(fill="Grey")
<- ggplot(foo, aes(x=1,y = trust_institut)) +
g0307 geom_violin(fill="Gold") + labs(x="density")
plot_grid(g0306, g0307, labels = c("Boxplot","Violin plot"),
label_size = 12
)
4.1.6 Quand la variable est qualitative
Quand la variable est qualitative, que ses modalités sont discrètes, la manière de représenter la plus commune est le fameux camembert que les experts abhorrent, n diagramme en barre représente mieux les proportions.
<-ggplot(df,aes(x=age))+
g08geom_bar(fill="skyblue")+
labs(title= "Distribution par classe d'âge",
caption="ESS2002-2018",
y= "fréquence",
x="Classes d'âge")
g08
Avec quelques améliorations : contrôle de la couleurs des barres, ajout des % et pivot pour une meilleure lecture.
<-df %>%
foofilter(!is.na(age))
<-ggplot(foo,aes(x=age, y = prop.table(stat(count)),label = scales::percent(prop.table(stat(count)))))+
g10geom_bar(aes(fill = age)) +
coord_flip()+
labs(title= "Répartition de la population par classe d'âge", caption="ESS2002-2018",y= "%",x="classes d'age") +
scale_y_continuous(labels = scales::percent)+ #contrôle de l'échelle des % et du format
scale_fill_brewer()+
geom_text(stat = 'count',position = position_dodge(.9), hjust = 1, size = 3)
g10
<-ggplot(foo,aes(x=factor(1),fill=age, y = prop.table(stat(count)),label =scales::percent(prop.table(stat(count)))))+
g11geom_bar(width=1) +
coord_flip()+
labs(title= "Répartition de la population par classe d'âge", caption="ESS2002-2018",y= "%",x="classes d'age") +
geom_text(stat = 'count',position = position_dodge(.9), hjust = 1, size = 3)
g11
si on tient au diagramme en secteur
<-df %>%filter(!is.na(age))
foo<-ggplot(foo,aes(x="", y = prop.table(stat(count)),
g10label = scales::percent(prop.table(stat(count)))))+
geom_bar(aes(fill = age)) +
labs(title= "Répartition de la population par classe d'âge",
caption="ESS2002-2018",y= "%",x="classes d'age") +
geom_text(stat = 'count',position = position_dodge(.9), hjust = 1, size = 3) +
coord_polar("y", start=0)
g10
https://cran.r-project.org/web/packages/treemapify/vignettes/introduction-to-treemapify.html
si on tient au diagramme en cercle, autant opter pour un treemap avec la bibliothèque treemapifi
library(treemapify)
<-df %>%
tree1mutate(n=1)%>%group_by(age) %>%
summarize(n=sum(n)) %>%
filter(!is.na(age))
<- ggplot(tree1, aes(area = n, fill=n),label=age) +
g11 geom_treemap() +
geom_treemap_text(aes(label=age),colour = "white", place = "centre",grow = FALSE)+
labs(title= "Répartition de la population par classe d'âge", caption="ESS2002-2018",y= NULL,x=NULL)
g11