Les graphiques de base

Informatique — R, chapitre 8

Une figure présentable s’obtient en R par une commande, sans réglage préalable. C’est un confort que peu de langages offrent. Ce chapitre couvre les graphiques dits « de base » — ceux fournis avec R — avant que le suivant n’expose la grammaire de ggplot2.

Les deux systèmes cohabitent sans se remplacer : le premier pour explorer vite, le second pour publier.

8.1 Le nuage de points

8.1.1 La commande minimale

set.seed(1) x <- rnorm(60) y <- 1.5 * x + rnorm(60) plot(x, y)

8.1.2 Habiller la figure

set.seed(1) x <- rnorm(60) y <- 1.5 * x + rnorm(60) plot(x, y, main = "Relation entre x et y", # titre xlab = "variable explicative", # axe des abscisses ylab = "variable expliquee", # axe des ordonnees pch = 19, # forme du point col = "#2f7ea8", # couleur cex = 1.2) # taille grid()
Argument Règle
pch forme du point : 1 cercle vide, 19 cercle plein, 17 triangle
col couleur, par nom ("red") ou code hexadécimal
cex taille des symboles, 1 par défaut
lwd épaisseur des traits
lty style de trait : 1 plein, 2 tirets, 3 pointillés

8.1.3 Superposer

Une commande plot crée une figure ; les suivantes y ajoutent.

set.seed(1) x <- rnorm(60) y <- 1.5 * x + rnorm(60) plot(x, y, pch = 19, col = "#8fa8b8", main = "Ajustement lineaire", xlab = "x", ylab = "y") abline(lm(y ~ x), col = "#c8542f", lwd = 2) # la droite des MCO points(0, 0, pch = 4, cex = 2, lwd = 2) # un point remarquable legend("topleft", legend = c("observations", "MCO"), col = c("#8fa8b8", "#c8542f"), pch = c(19, NA), lwd = c(NA, 2))
AvertissementL’ordre compte, et il n’y a pas de retour en arrière

abline, points, lines, text et legend dessinent par-dessus la figure courante. Si vous appelez plot une seconde fois, tout est effacé et une nouvelle figure commence.

On ne peut donc pas modifier une figure déjà tracée : il faut relancer la séquence entière. C’est la principale limite de ce système, et l’un des arguments en faveur de ggplot2.

8.2 Les graphiques d’une seule variable

8.2.1 L’histogramme

set.seed(3) x <- rnorm(300, mean = 10, sd = 2) hist(x, breaks = 20, freq = FALSE, col = "#cfe0ea", border = "white", main = "Distribution de x", xlab = "valeur", ylab = "densite") lines(density(x), col = "#c8542f", lwd = 2)

freq = FALSE passe des effectifs à la densité — indispensable pour superposer une courbe. breaks suggère un nombre de classes ; R l’ajuste pour obtenir des bornes rondes.

8.2.2 La boîte à moustaches

set.seed(5) d <- data.frame( valeur = c(rnorm(40, 10), rnorm(40, 12), rnorm(40, 9)), groupe = rep(c("A", "B", "C"), each = 40) ) boxplot(valeur ~ groupe, data = d, col = "#cfe0ea", main = "Distribution par groupe", ylab = "valeur")

La notation formule revient ici : valeur ~ groupe, comme au chapitre précédent. La boîte s’étend du premier au troisième quartile, le trait est la médiane, les moustaches vont jusqu’à 1,5 fois l’écart interquartile, et les points au-delà sont signalés comme atypiques.

8.2.3 Le diagramme en barres

region <- c("Nord", "Centre", "Centre", "Sud", "Nord", "Centre") barplot(table(region), col = "#2f7ea8", border = NA, main = "Effectifs par region", ylab = "nombre")

barplot attend des effectifs, pas les données brutes : d’où le passage par table.

8.3 Plusieurs figures côte à côte

set.seed(8) x <- rnorm(200) par(mfrow = c(2, 2)) # 2 lignes, 2 colonnes hist(x, main = "Histogramme", col = "#cfe0ea", border = "white") boxplot(x, main = "Boite a moustaches", col = "#cfe0ea") plot(x, type = "l", main = "Serie", col = "#2f7ea8") qqnorm(x, main = "Droite de Henry"); qqline(x, col = "#c8542f") par(mfrow = c(1, 1)) # revenir a une seule figure
AstucePensez à revenir en arrière

par(mfrow = ...) modifie un réglage global, qui reste actif pour toutes les figures suivantes de la session. Sans le par(mfrow = c(1, 1)) final, vos graphiques ultérieurs continueront de s’empiler dans une grille.

C’est une source d’étonnement fréquente : « pourquoi ma figure est-elle minuscule dans un coin ? »

8.4 Les séries temporelles

set.seed(12) serie <- cumsum(rnorm(120)) plot(serie, type = "l", col = "#2f7ea8", lwd = 2, main = "Une marche aleatoire", xlab = "temps", ylab = "niveau") abline(h = 0, lty = 2, col = "grey50") # ligne horizontale

L’argument type : "p" points, "l" ligne, "b" les deux, "h" bâtons, "s" escalier.

abline trace aussi des lignes de repère : h = pour une horizontale, v = pour une verticale.

8.5 Enregistrer une figure

png("figure.png", width = 900, height = 600, res = 120)
plot(x, y, pch = 19)
dev.off()                        # indispensable : ferme le fichier

Trois lignes, toujours dans cet ordre : ouvrir le fichier, dessiner, fermer.

Fonction Usage
png pour un site web ou une présentation
pdf pour un article ou un mémoire — vectoriel, ne pixelise jamais
svg pour le web, vectoriel également
Importantdev.off() n’est pas optionnel

Tant que vous ne l’appelez pas, R continue d’écrire dans le fichier et rien ne s’affiche à l’écran — au point qu’on croit ses commandes sans effet.

Pour un document LaTeX, préférez pdf : la figure restera nette à n’importe quel agrandissement, alors qu’un PNG se dégrade à l’impression.

8.6 Les couleurs

plot(1:8, rep(1, 8), pch = 19, cex = 4, col = c("red", "#2f7ea8", rgb(0.2, 0.6, 0.4), hcl.colors(5, "Blues")), xlab = "", ylab = "", axes = FALSE)

Par nom (colors() en donne 657), par code hexadécimal, ou par rgb. La fonction hcl.colors(n, palette) engendre une palette cohérente de n couleurs — plus sûr que de les choisir une à une.

AstuceDeux règles pour des figures lisibles

Ne codez pas une information par la seule couleur. Environ 8 % des hommes distinguent mal le rouge du vert. Doublez toujours la couleur par une forme (pch) ou un style de trait (lty).

Choisissez la palette selon la nature de la variable : "Blues" ou "Viridis" pour une variable continue, "Set2" pour des catégories sans ordre, "RdBu" pour un écart de part et d’autre d’un centre.

À vous

Simulez 200 valeurs d’une loi normale de moyenne 50 et d’écart-type 8. Tracez leur histogramme en densité, superposez la densité estimée et la densité théorique, et ajoutez une légende.

set.seed(99) x <- rnorm(200, mean = 50, sd = 8) # a completer
hist(x, breaks = 20, freq = FALSE,
     col = "#cfe0ea", border = "white",
     main = "Distribution simulee", xlab = "valeur")

lines(density(x), col = "#c8542f", lwd = 2)

grille <- seq(min(x), max(x), length.out = 200)
lines(grille, dnorm(grille, 50, 8), col = "#2f7ea8", lwd = 2, lty = 2)

legend("topright",
       legend = c("densite estimee", "densite theorique"),
       col = c("#c8542f", "#2f7ea8"), lwd = 2, lty = c(1, 2))

dnorm sert ici exactement comme au chapitre 7 : la hauteur de la densité en chaque point de la grille. L’écart entre les deux courbes illustre l’erreur d’estimation sur 200 observations.

Ce qu’il faut retenir

Écriture Effet
plot(x, y) nuage de points — crée une figure
main, xlab, ylab, pch, col, cex, lwd, lty l’habillage
abline, points, lines, text, legend ajouter à la figure courante
abline(lm(y ~ x)) la droite des moindres carrés
hist(x, freq = FALSE) histogramme en densité
density densité estimée, à superposer par lines
boxplot(y ~ groupe) comparer des distributions
barplot(table(v)) effectifs d’une qualitative
par(mfrow = c(2, 2)) grille de figures — pensez à revenir à c(1, 1)
png / pdfdev.off() enregistrer — la fermeture est obligatoire
hcl.colors une palette cohérente

Le chapitre suivant reprend les mêmes figures avec ggplot2, qui les construit par couches et permet, lui, de modifier un graphique après coup.