1 Graphiques avec R

Un outil essentiel de l'exploration et l'analyse de données est la visualisation graphique. Le langage R dispose d'une myriade de fonctions à cet effet.

De nombreuses page web sont dédiées aux graphiques avec R. Une référence complète en libre accès (en anglais) est disponible ici.

Nous montrons ici comment réaliser les graphiques les plus courants qui vous seront utiles pour vos rapports dans ce cours et dans les autres !

Remarque. Avoir des graphiques présentables (lisibles, compréhensibles et légendés) est essentiel pour produire une analyse de données. Il vous arrivera souvent d'avoir oublié comment effectuer telle ou telle représentation en R. Vous pouvez vous servir de références de base (comme celle-ci dessus), mais n'hésitez surtout pas à vous aidez de recherches Internet ! Il est très improbable que le souci que vous ayez n'ait jamais été rencontré (et résolu) par quelqu'un d'autre.

2 Les fonctions graphiques de base

La fonction plot() est la fonction élémentaire de graphique en R. Elle, permet (entre autres) de faire des nuages de points à partir de vecteurs.

x <- seq(-5, 5, by = 0.2) # Création d'un vecteur x
y <- x ^ 2 + 3 * x - 2    # Vecteur y, de même longueur que x
plot(x, y) # Le premier élément donne l'abscisse, le second l'ordonnée

# Tracé des données de iris
plot(iris$Sepal.Length, iris$Sepal.Width) 

Quand une des variables est catégorielle, R le detecte et fait un boxplot à la place d'un nuage de points.

plot(x = iris$Species, y = iris$Sepal.Length)

Pour faire un hitsogramme d'une variable quantitative, on utilise la fonction hist().

hist(iris$Sepal.Length) # On peut gérer le nombre de classes (voir help(hist))

3 Beaux graphiques avec ggplot2.

Le package ggplot2 implémente une vision unifiée des graphiques en R (gg signifie grammar of graphics). Il est le principal package utilisé pour faire de la visualisation de données, vous trouverez donc énormément d'aide sur internet ainsi que beaucoup d'extensions (ggforce, ggridges, **ggthemes*...).

library(ggplot2)

L'idée derrière ggplot2 est qu'un graphique peut toujours être pensé en découplant les différentes informations qui le composent :

  • les données,
  • les paramètres esthétiques : ce que l'on veut visualiser,
  • les géométriqes : la représentation que l'on veut,
  • les échelles : linéaire ou logarithmique, le choix des couleurs…,
  • les facettes : la subdivistion du graphique.

Toutes ces informations seront décomposées en plusieurs couches dans ggplot2, dans une syntaxe séquentielle.

3.1 Décomposition des couches

Supposons que l'on veuille représenter le jeu de données iris.

Commençons par créer un nuage de points comme précédemment.

ggplot(iris) # On spécifie les données

Comme on ne sait pas ce que l'on va afficher, on a simplement un rectangle vide.

Mais au fait, que veut on représenter ?

Par exemple, on veut représenter la largeur des sépales en fonction de leur longueur. On spécifie alors les variables d'intérêt (ou esthétiques) dans une fonction dédiée, la fonction aes().

ggplot(iris) + # On spécifie les données
  aes(x = Sepal.Length, y = Sepal.Width) # On spécifie abscisses et ordonnées

La fonction aes() peut prendre plusieurs arguments pour faire correspondre les données et les représnetasions. Les deux plus courants sont x (l'abscisses) et y (l'ordonnée). On utilisera plus bas d'autres arguments comme color, fill ou shape.

L'échelle est apparue mais il faut encore dire à ggplot() comment on veut représenter nos variables. Par exemple sous la forme de points. La forme de représentation sera toujours spécifiée dans une fonction commençant par geom_ :

ggplot(iris) + # On spécifie les données
  aes(x = Sepal.Length, y = Sepal.Width) + # On spécifie abscisses et ordonnées
  geom_point() # Sous forme de point, avec le prefixe geom_

3.2 Différentes esthétiques

Il est possible de spécifier d'autres paramètres esthétiques, comme la couleur ou la forme des points.

ggplot(iris) + # On spécifie les données
  aes(x = Sepal.Length, y = Sepal.Width, # On spécifie abscisses et ordonnées
      color = Species) + # L'esthétique de couleur sera donné par l'espèce 
  geom_point() # Sous forme de point, avec le prefixe geom_

Il est intéressant de mettre de la redondance dans la légende (la couleur et la forme sont toutes deux associées à l'espèce) pour faciliter la lecture aux personnes daltoniennes ou après une impression en noir et blanc.

ggplot(iris) + # On spécifie les données
  aes(x = Sepal.Length, y = Sepal.Width,  # On spécifie abscisses et ordonnées
      color = Species, shape = Species) + # Forme et couleur données par l'espèce 
  geom_point() # Sous forme de point, avec le prefixe geom_

Exercice

Avec le jeu de données mtcars, représentez la consommation (sous la forme miles per gallon, colonne mpg) en fonction du poids des véhicules (colonne wt). Dans un second temps, vous modifierez la taille des points (esthétique size) en fonction du nombre de cylindes (colonne cyl).

ggplot(data = mtcars) # Complétez!

# Premier indice
# On précise les esthétiques avec + aes(x = ..., y = ...) 
# Et on précise qu'on veut des points avec + geom_point()
# Second indice
# dans aes, ajoutez size = cyl
# Solution
ggplot(mtcars) + 
  aes(x = wt, y = mpg, size = cyl) + 
  geom_point()

4 Graphiques classiques: geom_

On dispose évidemment de toute la palette graphique usuelle.

  • geom_boxplot() permet de tracer des boîtes à moustaches.
ggplot(iris) + # Données
  aes(x = Species, y = Sepal.Length) + # Variables à représenter (esthétiques)
  geom_boxplot() # Représentation

  • geom_histogram() permet de tracer des histogrammes.
ggplot(iris) + # Données
  aes(x = Sepal.Length) + # Variables à représenter (esthétiques)
  geom_histogram() # Représentation

  • geom_bar permet de tracer des diagrammes en bâtons en comptant les effectifs à notre place.
ggplot(carData::TitanicSurvival) + # Données (passagers du Titanic)
  aes(x = passengerClass) + # Variables à représenter (esthétiques)
  geom_bar() # Représentation (l'ordonnée est le nombre dans chaque classe)

  • geom_col() permet de tracer des diagrammes en bâtons dont on connaît déjà la hauteur.
library(dplyr)
mtcars %>%
  mutate(ID = row_number()) %>% # Crée une variable correspondant au numéro de l'observation
  ggplot() +
  aes(x = ID, y = hp) + # On regarde la puissance de chaque voiture
  geom_col()            #  sous la forme d'un diagramme en bâton

Pour représenter les comptages avec geom_col, on doit d'abord calculer l'effectif dans chaque groupe, via la fonction count(), avant de l'assigner à l'axe y.

count(mtcars, gear) # Rappel : count() compte le nombre d'occurence
  gear  n
1    3 15
2    4 12
3    5  5

Une fois la hauteur de chaque bâton obtenue, on utilise geom_col().

mtcars %>% # On manipule le data.frame en amont
  count(gear) %>%
  ggplot() + # On fournit à ggplot le nombre d'occurence tel quel
  aes(x = gear, y = n) + # chaque barre sera sur gear et aura n comme hauteur
  geom_col(color = "black")

Ici, on a utilisé l'opérateur pipe %>% pour effectuer une transformation du data.frame sans avoir besoin de l'assigner à une nouvelle variable.

Exercice

Représentez l'histogramme de la distribution de la largeur des sépales (colonne Sepal.Width) des iris. Dans un second temps, vous ne mettrez que 10 bins (option bins = ... dans geom_histogram). Ensuite, vous colorerez les histogrammes en fonction de l'espèce d'iris (en utilisant l'esthétique fill = Species dans l'aes).

ggplot(iris)

# Solution
ggplot(iris) + # Données
  aes(x = Sepal.Width, fill = Species) + # Variables à représenter (esthétiques)
  geom_histogram(bins = 10) # Représentation

# Si on veut éviter la superposition, on pourra ajouter position = "dodge"

5 Couleurs

Evidemment, on peut représenter les couleurs selon les goûts de chacun.

# col est la couleur du contour, fill est la couleur de remplissage
ggplot(iris) + # Données
  aes(x = Sepal.Length) + # Variables à représenter (esthétiques)
  geom_histogram(fill = "grey", col = "black") # Représentation

Ces couleurs ne dépendent pas des données, c'est pour cela qu'elles ne sont pas précisées dans la fonction aes() mais directement dans le geom_.

Ainsi, pour les passagers du Titanic, on peut regarder les effectifs par classe et par sexe.

ggplot(carData::TitanicSurvival) + # Données (passagers du Titanic)
  aes(x = passengerClass, fill = sex) + # Variables à représenter (esthétiques)
  geom_bar() # Représentation (l'ordonnée est le nombre dans chaque classe)

Cette représentation pouvant être faite côte à côte.

ggplot(carData::TitanicSurvival) + # Données (passagers du Titanic)
  aes(x = passengerClass, fill = sex) + # Variables à représenter (esthétiques)
  geom_bar(position = "dodge") # Position relative des bâtons

6 Légendes et titres

Un graphique présentable se doit d'avoir un titre et des légendes lisibles et compréhensibles. Par exemple, dans un rapport, on ne voudra pas voir l'axe des abscisses légendé par Sepal.Length (d'autant moins si le rapport est en français). Ceci se fait avec la fonction labs() qui prend comme argument des noms (chaînes de caractères) associés aux esthétiques.

ggplot(iris) + # Données
  aes(x = Sepal.Length, y = Sepal.Width, color = Species) + # Esthétiques
  geom_point() + # Représentation
  labs(x = "Longueur des sépales", y = "Largeur des sépales",
       color = "Espèce", # Nom de chacun des axes : abscisses, ordonnées et couleurs
       title = "Taille des sépales de différentes espèces d'iris") # Titre

Ainsi, tout paramètre esthétique présent dans aes() doit avoir son alter ego dans labs().

7 Préparation des données

7.1 Renommage des labels

Dans le cas du Titanic, le tableau de données est en anglais. Quand on souhaite faire la représentation dans un rapport en français, on voudra, pour les besoins du graphiques, écrire, les choses en français. Pour cela, il est souvent utile de renommer les facteurs (voir la Session 1).

Faites-le avant le graphique, grâce au %>%!

carData::TitanicSurvival %>% # Données initiales
  # mutate() permet de modifier une colonne, ici sex et passengerClass
  mutate(sex = factor(sex, labels = c("Femme", "Homme")), # Renommage des modalités
    passengerClass = factor(passengerClass,
                            labels = c("1ère", "2ème", "3ème"))) %>%
  ggplot() + # On va représenter ces données modifiées
  aes(x = passengerClass, fill = sex) + # Variables à représenter (esthétiques)
  geom_bar(position = "dodge") + # Position relative des bâtons
  labs(x = "Classe de voyage", y = "Effectif", fill = "Sexe", # Titre des axes
       title = "Répartition des passagers du Titanic") # Titre du graphique

7.2 Transformation de type

Dans un esprit similaire à celui du renommage, il arrive parfois qu'une variable catégorielle soit codée comme numérique. La représentation graphique est alors mauvaise.

ggplot(mtcars) +
  aes(x = hp, y = mpg, size = cyl, # La taille des points est une esthétique
      color = am) + # am vaut soit 0 soit 1
  geom_point() +    #  mais est considéré comme continu !
  labs(x = "Puissance", y = "Consommation (Miles/Gallon)",
       size = "Nombre de cylindres", color = "Transmission",
       title = "Consommation des véhicules")

Il est alors nécessaire de la repasser en facteur, on va manipuler le data.frame en amont avec dplyr.

mtcars %>%
  mutate(am = factor(am,  # On transforme am en facteur
                     labels = c("Automatique", "Manuelle"))) %>% # Noms des niveaux
  ggplot() + # Les données transformées servent d'entrée à ggplot
  aes(x = hp, y = mpg, size = cyl, color = am) + # Esthétiques
  geom_point() + # Représentation
  labs(x = "Puissance", y = "Consommation (Miles/Gallon)",
       size = "Nombre de cylindres", color = "Transmission",
       title = "Consommation des véhicules")

On a ici quatre "axes" sur lesquels sont représentés les données : l'abscisse, l'ordonnée, la couleur et la taille. On aurait pu également rajouter une autre variable sur la forme des points mais il faut faire attention à ne pas surcharger les graphiques.

8 Graphiques multiples

Il est possible d'avoir une fenêtre graphique par modalité d'une variable qualitative (ici l'espèce) avec facet_grid() ou facet_wrap().

Un graphique par colonne...

ggplot(iris) +
  aes(x = Sepal.Length, fill = Species) + # Le remplissage dépend de l'espèce
  geom_histogram(color = "black", show.legend = FALSE) + # Le contour est commun
  # On ne montre pas la légende
  facet_grid(Species ~ .) +   # Species en ligne, le point signifie l'absence de variable en colonne
  labs(x = "Longueur des sépales", y = "Effectif",
       title = "Distribution des longueurs de sépale par espèce d'iris")

... ou par ligne !

ggplot(iris) +
  aes(x = Sepal.Length, fill = Species) + # Le remplissage dépend de l'espèce
  geom_histogram(color = "black", show.legend = FALSE) + # Le contour est commun
  # On ne montre pas la légende
  facet_grid(. ~ Species) +   # Species en ligne, le point signifie l'absence de variable en ligne
  labs(x = "Longueur des sépales", y = "Effectif",
       title = "Distribution des longueurs de sépale par espèce d'iris")

9 Pour aller plus loin

9.1 Encore plus d'options

Pour des raison esthétiques ou d'économie d'encre, on peut changer le thème de fond.

ggplot(iris) +
  aes(x = Petal.Length, y = Petal.Width, color = Species) +
  geom_point() +
  theme_bw() # Thème blanc

ggplot(iris) +
  aes(x = Petal.Length, y = Petal.Width, color = Species) +
  geom_point() +
  theme_minimal() # Le même mais sans le cadre

ggplot(iris) +
  aes(x = Petal.Length, y = Petal.Width, color = Species) +
  geom_point() +
  ggthemes::theme_economist() # Le thème utilisé par The Economist

On peut changer le thème qui sera appliqué par défaut via theme_set().

theme_set(theme_minimal())

Parfois, la légende est redondante avec l'axe. On peut la retirer dans les options de theme().

ggplot(iris) +
  aes(x = Species, y = Sepal.Width, fill = Species) + # Le remplissage se choisit avec fill
  geom_boxplot() +
  theme(legend.position = "none")

Ou on peut aussi la mettre dans le graphique pour gagner de la place.

ggplot(iris) +
  aes(x = Petal.Width, y = Petal.Length, color = Species) +
  geom_point() +
  theme(legend.position = c(0.8, 0.2))

ggplot2 fonctionnant en couches, il est possible de combiner des geom_, en les assemblant avec des +.

ggplot(iris) +
  aes(x = Sepal.Length, y = Petal.Length, color = Species) +
  geom_point() +
  geom_vline(xintercept = 7) +
  geom_hline(yintercept = 3, color = "red", linetype = "dashed")

Il est également possible de combiner plusieurs data.frame. Ceci peut être utilisé pour ajouter les moyennes sur des boîtes à moustaches par exemple.

iris_mean <- # On calcule les moyennes
  iris %>%
  group_by(Species) %>%
  summarise(Mean = mean(Petal.Width))
`summarise()` ungrouping output (override with `.groups` argument)
ggplot(iris) +
  aes(x = Species, y = Petal.Width) +
  geom_boxplot() + # On trace les boxplots
  geom_point(data = iris_mean, mapping = aes(y = Mean), # On ajoute le data.frame des moyennes
             color = "red", size = 4, shape = "X") # Représentées par des croix rouges

9.2 Package cowplot

cowplot est un package qui permet d'arranger des graphiques sans lien entre eux dans une même image.

p1 <-
  ggplot(iris) +
  aes(x = Sepal.Width, y = Sepal.Length) +
  geom_point()

p2 <-
  ggplot(iris) +
  aes(x = Petal.Width, y = Petal.Length) +
  geom_point()

cowplot::plot_grid(p1, p2)