Chapitre 5 Graphiques en R

R est très puissant en termes de représentations graphiques. Créer des graphiques en R peut se faire à l’aide de plusieurs packages:

  • graphics (viens charger d’office avec R): système de base en R.

  • lattice: ajoute plus de fonctionnalités au package de base. Ce package ne sera pas traité ici,

  • ggplot2: une approche beaucoup plus moderne qui permet de créer des graphiques de qualité professionnelle.

Pour illustrer les graphiques en R, nous allons utiliser les données mpg disponibles dans le package ggplot2.

head(mpg)
# A tibble: 6 x 11
  manufacturer model displ  year   cyl trans  drv     cty   hwy fl    class
  <chr>        <chr> <dbl> <int> <int> <chr>  <chr> <int> <int> <chr> <chr>
1 audi         a4      1.8  1999     4 auto(~ f        18    29 p     comp~
2 audi         a4      1.8  1999     4 manua~ f        21    29 p     comp~
3 audi         a4      2    2008     4 manua~ f        20    31 p     comp~
4 audi         a4      2    2008     4 auto(~ f        21    30 p     comp~
5 audi         a4      2.8  1999     6 auto(~ f        16    26 p     comp~
6 audi         a4      2.8  1999     6 manua~ f        18    26 p     comp~

On peut avoir une description de ces données et leur nature à l’aide de ?mpg et

str(mpg)
Classes 'tbl_df', 'tbl' and 'data.frame':   234 obs. of  11 variables:
 $ manufacturer: chr  "audi" "audi" "audi" "audi" ...
 $ model       : chr  "a4" "a4" "a4" "a4" ...
 $ displ       : num  1.8 1.8 2 2 2.8 2.8 3.1 1.8 1.8 2 ...
 $ year        : int  1999 1999 2008 2008 1999 1999 2008 1999 1999 2008 ...
 $ cyl         : int  4 4 4 4 6 6 6 4 4 4 ...
 $ trans       : chr  "auto(l5)" "manual(m5)" "manual(m6)" "auto(av)" ...
 $ drv         : chr  "f" "f" "f" "f" ...
 $ cty         : int  18 21 20 21 16 18 18 18 16 20 ...
 $ hwy         : int  29 29 31 30 26 26 27 26 25 28 ...
 $ fl          : chr  "p" "p" "p" "p" ...
 $ class       : chr  "compact" "compact" "compact" "compact" ...

Commençons par transformer cyl, drv, fl et class en facteur.

mpg <- transform(mpg, cyl = factor(cyl), drv = factor(drv), fl = factor(fl), 
    class = factor(class))

5.1 Système graphique de base (graphics)

Parmi les fonctions disponibles il y a plot, hist, stripchart, qqnorm, pie, barplot,…. Voici quelques exemples de graphiques de base.

plot est la fonction principale pour tracer des graphiques en R. C’est aussi une fonction générique dont le comportement s’adapte à la nature de ses arguments.

plot(mpg$displ)  # scatterplot, 1 num vs index (type='p')

plot(mpg$displ, type = "l")  # scatterplot, 1 num vs index (type='l')

plot(mpg$drv)  # barplot, 1 facteur

plot(mpg$displ, mpg$hwy)  # scatterplot, 2 vec. num

plot(mpg$drv, mpg$cyl)  # barplot, 2 facteurs

plot(mpg$drv, mpg$displ)  # boxplot, 1 num vs facteur

plot(density(mpg$displ))  # density plot, 1 facteur

plot(sin, from = -2 * pi, to = 2 * pi)  # tracer la fonct. sin

plot(function(x) x^2, from = -1, to = 1)  # tracer la fonct. x^2

hist(mpg$displ)  # histogramme, 1 num

stripchart(mpg$displ, method = "stack")  # stripchart, 1 num

5.2 Le package ggplot2

ggplot2 repose sur les principes de la grammaire des graphiques. L’idée principale est de concevoir un graphique comme une succession de couches (layer) qui constituent la grammaire de la syntaxe.

Les principales couches de la grammaire sont :

  • Le jeu de données qui contient les variables que l’on veut représenter. Cela se fait avec la fonction ggplot.

  • La ou les variables à représenter (x et/ou y) et les éléments esthétiques tels que couleur (color), taille (size) et remplissage (fill) des objets à représenter. Cela se fait avec la fonction aes.

  • Le type de représentation graphique souhaitée (nuage de points, diagramme en barres, histogramme, etc.). Cela se fait avec les fonctions geom_xxx, ou xxx représente le type souhaité (ex., point, bar, histogram, boxplot, etc.).

Il y a deux options pour écrire le code:

  1. ggplot(Donnees) + aes(x = varX, y = varY) + geom_xxx()

  2. qplot(x = varX, y = varY, data = Donnees, geom = 'xxx')

Dans l’option 1, Donnees est le nom du data frame qui contient les vriables varX et varY. Le symbole + permet d’indiquer quelles sont les différentes couches qui seront ajoutées au fur et à mesure. C’est la façon la plus transparente pour écrire le code. C’est aussi elle qui permet un contrôle plus fin de tous les paramètres graphiques. qplot est la fonction de base qu’offre la librairie ggplot2 pour le tracé de graphiques simples rapidement et avec le minimum de complexité. Elle est pour ggplot2 ce que la fonction plot est pour graphics (la librairie graphique de base de R).

Par la suite nous allons réaliser une série de graphiques en utilisant l’approche 1.

Diagramme à point: geom="point"

  • Deux varaibles numériques
qplot(x = displ, y = hwy, data = mpg, geom = "point")
# ou
qplot(x = displ, y = hwy, data = mpg)
ggplot(mpg) + aes(x = displ, y = hwy) + geom_point()
# ou
ggplot(mpg, aes(x = displ, y = hwy)) + geom_point()

  • Numérique et facteur
qplot(x = drv, y = hwy, data = mpg)
ggplot(mpg) + aes(x = drv, y = hwy) + geom_point()

qplot(x = drv, y = hwy, data = mpg, geom = "blank") + geom_jitter(width = 0.2, 
    height = 0)
ggplot(mpg) + aes(x = drv, y = hwy) + geom_jitter(width = 0.2, height = 0)

qplot(y = drv, x = hwy, data = mpg)
ggplot(mpg) + aes(y = drv, x = hwy) + geom_point()

qplot(y = drv, x = hwy, data = mpg, geom = "blank") + geom_jitter(width = 0, 
    height = 0.2)
ggplot(mpg) + aes(y = drv, x = hwy) + geom_jitter(width = 0, height = 0.2)

  • Une variable numérique
qplot(y = hwy, data = mpg)
ggplot(mpg) + aes(x = 1:nrow(mpg), y = hwy) + geom_point()  # num vs index

qplot(x = "", y = hwy, data = mpg)
ggplot(mpg) + aes(x = "", y = hwy) + geom_point()

qplot(y = hwy, data = mpg) + geom_line()
ggplot(mpg) + aes(x = 1:nrow(mpg), y = hwy) + geom_point() + geom_line()

La forme des points: shape

Il y a plusieurs aspects esthétiques qui peuvent être modifiés. En tapant ?geom_points dans la console R, vous accédez à la documentation complète.

Vous pouvez, par exemple, choisir de modifier la forme des points. Pour ce faire, vous devez savoir quelles formes sont disponibles et comment vous pouvez les appeler.

qplot(x = displ, y = hwy, data = mpg, shape = I(8))
ggplot(mpg) + aes(x = displ, y = hwy) + geom_point(shape = 8)

On peut aussi faire varier la forme en fonction des valeurs prises par une autre variable. Dans ce cas, il faut placer shape à l’intérieur de aes.

qplot(x = displ, y = hwy, data = mpg, shape = drv)
ggplot(mpg) + aes(x = displ, y = hwy, shape = drv) + geom_point()

Autres attributs: Couleur: color, Transparence: alpha et Taille: size

Suivant le même principe, on peut modifier la couleur, la taille et/ou la transparence des points. Voici quelques exemples.

qplot(x = displ, y = hwy, data = mpg, color = I("red"))
ggplot(mpg) + aes(x = displ, y = hwy) + geom_point(color = "red")

qplot(x = displ, y = hwy, data = mpg, color = cty)
ggplot(mpg) + aes(x = displ, y = hwy, color = cty) + geom_point()

qplot(x = displ, y = hwy, data = mpg, size = I(2))
ggplot(mpg) + aes(x = displ, y = hwy) + geom_point(size = 2)

qplot(x = displ, y = hwy, data = mpg, alpha = I(0.2))
ggplot(mpg) + aes(x = displ, y = hwy) + geom_point(alpha = 0.2)

L’argument alpha prend une valeurs comprise entre 0 (transparence) et 1 (opacité totale) et permet de réduire le problème du chevauchement des points

On peut évidemment mixer ces éléments pour construire des graphiques de plus en plus complexes.

qplot(x = displ, y = hwy, data = mpg, color = drv, shape = drv, size = I(2.5))
ggplot(mpg) + aes(x = displ, y = hwy, color = drv, shape = drv) + geom_point(size = 2.5)

qplot(x = displ, y = hwy, data = mpg, color = cty, shape = drv, size = I(2.5))
ggplot(mpg) + aes(x = displ, y = hwy, color = cty, shape = drv) + geom_point(size = 2.5)

qplot(x = drv, y = hwy, data = mpg, size = I(2.5), alpha = I(0.1))
ggplot(mpg) + aes(x = drv, y = hwy) + geom_point(size = 2.5, alpha = 0.1)

Pour ajouter ou modifier les titres des graphiques (titre principal, étiquettes des axes, les titres des légendes, …), on peut utiliser la fonction labs. Voici un exemple:

qplot(x = displ, y = hwy, data = mpg, color = cty) + labs(title = "Fuel economy data from 1999 and 2008 for 38 popular models of car", 
    x = "Engine displacement, in litres", y = "Highway miles per gallon", color = "City miles per gallon", 
    subtitle = "Only models which had a new release every year", caption = "Data from fueleconomy.gov")
ggplot(mpg) + aes(x = displ, y = hwy, color = cty) + geom_point() + labs(title = "Fuel economy data from 1999 and 2008 for 38 popular models of car", 
    x = "Engine displacement, in litres", y = "Highway miles per gallon", color = "City miles per gallon", 
    subtitle = "Only models which had a new release every year", caption = "Data from fueleconomy.gov")

Faceting: l’argument facets

Le ``faceting" permet de diviser le même graphique en plusieurs panneaux selon les valeurs d’un ou plusieurs facteurs.

qplot(x = displ, y = hwy, data = mpg, facets = drv ~ .)
ggplot(mpg) + aes(x = displ, y = hwy) + geom_point() + facet_grid(drv ~ .)

qplot(x = displ, y = hwy, data = mpg, facets = . ~ drv)
ggplot(mpg) + aes(x = displ, y = hwy) + geom_point() + facet_grid(. ~ drv)

qplot(x = displ, y = hwy, data = mpg, facets = drv ~ fl)
ggplot(mpg) + aes(x = displ, y = hwy) + geom_point() + facet_grid(drv ~ fl)

Histogramme: geom="histogram" et densité: geom="density"

qplot(x = hwy, data = mpg, geom = "histogram")
# ou
qplot(x = hwy, data = mpg)
ggplot(mpg) + aes(x = hwy) + geom_histogram()
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

De plus, outre les paramètres esthétiques tels que la couleur nous avons des paramètres propres aux histogrammes tels que la largeur des intervalles binwidth.

qplot(x = hwy, data = mpg, binwidth = 2, color = I("black"), fill = I("grey"))
ggplot(mpg) + aes(x = hwy) + geom_histogram(binwidth = 2, color = "black", fill = "grey")

qplot(x = hwy, y = ..density.., data = mpg, geom = "histogram", binwidth = 2)
ggplot(mpg) + aes(x = hwy, y = ..density..) + geom_histogram(binwidth = 2)  # y=..density.. --> surface=1

qplot(x = hwy, data = mpg, geom = "density")
ggplot(mpg) + aes(x = hwy) + geom_density()

qplot(x = hwy, data = mpg, geom = "density", bw = 5)
ggplot(mpg) + aes(x = hwy) + geom_density(bw = 5)

qplot(x = hwy, y = ..density.., data = mpg, geom = "histogram", binwidth = 2) + 
    geom_density(size = 1)
ggplot(mpg) + aes(x = hwy, y = ..density..) + geom_histogram(binwidth = 2) + 
    geom_density(size = 1)

qplot(x = hwy, data = mpg, geom = "density", color = drv, fill = drv, size = I(1), 
    alpha = I(0.05))
ggplot(mpg) + aes(x = hwy, color = drv, fill = drv) + geom_density(size = 1, 
    alpha = 0.05)

Boîte à moustaches : geom="boxplot"

qplot(x = "", y = hwy, data = mpg, geom = "boxplot")
ggplot(mpg) + aes(x = "", y = hwy) + geom_boxplot()

qplot(x = drv, y = hwy, data = mpg, geom = "boxplot")
ggplot(mpg) + aes(x = drv, y = hwy) + geom_boxplot()

qplot(x = drv, y = hwy, data = mpg, geom = "boxplot", varwidth = TRUE)
ggplot(mpg) + aes(x = drv, y = hwy) + geom_boxplot(varwidth = TRUE)  # varier la largeur des boîtes en fonction des effectifs de la classe

qplot(x = drv, y = hwy, data = mpg, geom = "boxplot") + geom_jitter(alpha = 0.2, 
    size = 2, width = 0.1, height = 0)
ggplot(mpg) + aes(x = drv, y = hwy) + geom_boxplot() + geom_jitter(alpha = 0.2, 
    size = 2, width = 0.1, height = 0)

qplot(x = drv, y = hwy, data = mpg, geom = "boxplot", facets = . ~ class)
ggplot(mpg) + aes(x = drv, y = hwy) + geom_boxplot() + facet_grid(. ~ class)

Diagramme en barres : geom="bar"

qplot(x = drv, data = mpg, geom = "bar")
# ou
qplot(x = drv, data = mpg)
ggplot(mpg) + aes(x = drv) + geom_bar(stat = "count")
# ou
ggplot(mpg) + aes(x = drv) + geom_bar()

qplot(x = drv, data = mpg, fill = class)
ggplot(mpg) + aes(x = drv, fill = class) + geom_bar()

qplot(x = drv, data = mpg, fill = class, geom = "blank") + geom_bar(position = "dodge")
ggplot(mpg) + aes(x = drv, fill = class) + geom_bar(position = "dodge")

Quelques astuces

Pour avoir de l’aide et plus d’information sur ce qui suit, googler le nom des packages et/ou des fonctions utilisé dans le code.

Création et manipulation interactive de graphes

require(esquisse)
esquisser(mpg)
esquisser(mpg)

Figure 5.1: esquisser(mpg)

require(ggplotgui)
ggplot_shiny(mpg)
ggplot_shiny(mpg)

Figure 5.2: ggplot_shiny(mpg)

Graphique dynamique (plotly)

p <- ggplot(mpg) + aes(x = displ, y = hwy) + geom_point()
p

require(plotly)
ggplotly(p)

Combiner plusieurs graphiques (patchwork)

p1 <- ggplot(mpg) + aes(x = displ, y = hwy) + geom_point()
p2 <- ggplot(mpg) + aes(x = hwy) + geom_histogram(binwidth = 2)
p3 <- ggplot(mpg) + aes(y = hwy) + geom_boxplot()
require(patchwork)
p1 + p2

p1/p2

p1 + p2/p3

(p1 + p2)/p3

5.3 Exercices

Exercice 1

À partir des données tips du package reshape2, refaire le graphique suivant

require(reshape2)
ggplot(tips) + aes(x = total_bill, y = tip) + geom_point()
ggplot(tips) + aes(x = sex, y = total_bill) + geom_point(alpha = 0.2) + facet_grid(. ~ 
    smoker)
ggplot(tips) + aes(x = sex, y = total_bill) + geom_boxplot(varwidth = TRUE) + 
    facet_grid(. ~ smoker)
ggplot(tips) + aes(x = total_bill, y = tip, color = sex) + geom_point()
ggplot(tips) + aes(x = total_bill, y = tip, color = sex) + geom_point() + facet_grid(sex ~ 
    .)
ggplot(tips) + aes(x = cut(total_bill, breaks = c(3, 18, 25, 51)), y = tip) + 
    geom_boxplot() + facet_grid(. ~ sex) + labs(x = "total_bill")
ggplot(tips) + aes(x = total_bill, y = tip, shape = smoker) + geom_point() + 
    facet_grid(smoker ~ sex)
require(reshape2)
qplot(total_bill, tip, data = tips)
qplot(sex, total_bill, data = tips, facets = . ~ smoker, alpha = I(0.2))
qplot(sex, total_bill, data = tips, facets = . ~ smoker, geom = "boxplot", varwidth = TRUE)
qplot(total_bill, tip, data = tips, color = sex)
qplot(total_bill, tip, data = tips, color = sex, facets = sex ~ .)
qplot(cut(total_bill, breaks = c(3, 18, 25, 51)), tip, data = tips, facets = ~sex, 
    geom = "boxplot") + labs(x = "total_bill")
qplot(total_bill, tip, data = tips, shape = smoker, facets = smoker ~ sex)