ggplot2
- ExemplesCe document accompagne la présentation Visualisation_ggplot2_RaQ2019.pdf
.
Ouvrir ce document en RStudio (version 1.0 ou plus récente). Il s’agit d’un fichier R Markdown.
Si les accents s’affichent mal, allez dans le menu « File > Reopen with Encoding… », sélectionnez « UTF-8 », puis cliquez sur « OK ».
Cliquez sur le petit triangle vert en haut à droite d’un bloc de code pour faire rouler le code qu’il contient.
print("Ceci est un test")
## [1] "Ceci est un test"
Si le résultat produit par le code ne s’affiche pas directement dans le fichier (s’il s’affiche plutôt dans la console R), veuillez :
vous assurer que « Chunk Output Inline » est sélectionné dans les options du fichier (roue d’engrenage dans la barre dans le haut du fichier);
si ça ne fonctionne toujours pas, allez dans le menu « Tools > Global Options… > R Markdown » et cochez « Show output inline for all R Markdown documents », puis cliquez sur « OK ».
Si RStudio plante (ne répond plus), c’est parce que vous utilisez une version de RStudio qui comporte malheureusement un bogue. Mettez à jour votre version de RStudio par la suivante : https://s3.amazonaws.com/rstudio-ide-build/desktop/windows/RStudio-1.2.1518.exe (Source : https://github.com/rstudio/rstudio/issues/4759).
Remarque : Vous pouvez aussi consulter le fichier HTML obtenu de la compilation du présent fichier R Markdown \(\rightarrow\) Visualisation_ggplot2_RaQ2019_Exemples.html
Data frame quakes
du package datasets
(chargé par défaut lors de l’ouverture de session), auquel on ajoute deux variables catégoriques comme suit :
quakes$magFactor <- factor(floor(quakes$mag)) # classe de magnitude
quakes$region <- factor(quakes$long >= 175, labels = c("Ouest", "Est")) # région
str(quakes)
## 'data.frame': 1000 obs. of 7 variables:
## $ lat : num -20.4 -20.6 -26 -18 -20.4 ...
## $ long : num 182 181 184 182 182 ...
## $ depth : int 562 650 42 626 649 195 82 194 211 622 ...
## $ mag : num 4.8 4.2 5.4 4.1 4 4 4.8 4.4 4.7 4.3 ...
## $ stations : int 41 15 43 19 11 12 43 15 35 19 ...
## $ magFactor: Factor w/ 3 levels "4","5","6": 1 1 2 1 1 1 1 1 1 1 ...
## $ region : Factor w/ 2 levels "Ouest","Est": 2 2 2 2 2 2 1 2 2 2 ...
ggplot2
Il faut d’abord charger le package ggplot2
.
library(ggplot2)
Voici notre premier exemple.
ggplot(data = quakes) + geom_point(mapping = aes(x = mag, y = stations))
Références :
On peut initialiser un graphique, que l’on stocke dans un objet.
monGraph <- ggplot(data = quakes)
Puis lui ajouter des couches.
monGraph <- monGraph + geom_point(mapping = aes(x = mag, y = stations))
On peut observer le contenu de l’objet.
str(monGraph)
summary(monGraph)
## data: lat, long, depth, mag, stations, magFactor, region [1000x7]
## faceting: <ggproto object: Class FacetNull, Facet, gg>
## compute_layout: function
## draw_back: function
## draw_front: function
## draw_labels: function
## draw_panels: function
## finish_data: function
## init_scales: function
## map_data: function
## params: list
## setup_data: function
## setup_params: function
## shrink: TRUE
## train_scales: function
## vars: function
## super: <ggproto object: Class FacetNull, Facet, gg>
## -----------------------------------
## mapping: x = ~mag, y = ~stations
## geom_point: na.rm = FALSE
## stat_identity: na.rm = FALSE
## position_identity
Et enfin produire un graphique à partir de l’objet, simplement en l’affichant.
monGraph # ou print(monGraph)
Pour enregistrer le graphique dans un fichier externe, on utilise la fonction ggsave.
ggsave(file = "quakes_stations_vs_mag.png", plot = monGraph)
Référence :
ggplot(data = quakes) +
geom_point(mapping = aes(x = mag, y = stations)) +
labs(title = "1000 séismes près de Fiji") + # ou ggtitle("...") +
labs(x = "magnitude du séisme") + # ou xlab("...") +
labs(y = "nombre de stations rapportant le séisme") # ou ylab("...")
Vous avez envie de centrer le titre du graphique ? Voici comment faire.
ggplot(data = quakes) +
geom_point(mapping = aes(x = mag, y = stations)) +
labs(title = "1000 séismes près de Fiji") +
theme(plot.title = element_text(hjust = 0.5)) + # permet de centrer le titre du graphique
labs(x = "magnitude du séisme") +
labs(y = "nombre de stations rapportant le séisme")
Références :
Le graphique précédent représente deux variables. Ajoutons une troisième variable au graphique, qui fera varier la couleur des points. Si la palette de couleur utilisée par défaut ne nous plaît pas, on peut la changer.
scatterplot <- ggplot(data = quakes) +
geom_point(mapping = aes(
x = mag,
y = stations,
colour = depth # permet de faire varier la couleur des points en fonction de la var. depth
)) +
labs(title = "1000 séismes près de Fiji") +
theme(plot.title = element_text(hjust = 0.5)) +
labs(x = "magnitude du séisme") +
labs(y = "nombre de stations rapportant le séisme") +
labs(colour = "profondeur") + # permet de modifier le titre de la légende
scale_colour_continuous(type = "viridis") # permet d'utiliser la palette de couleur viridis
scatterplot
Référence :
Ajoutons maintenant une quatrième variable au graphique, celle-ci catégorique, en créant des graphiques disjoints selon le niveau de la variable.
scatterplot +
facet_wrap(facets = ~ region) # permet de créer un panneau par niveau de la variable region
Référence :
facet_wrap
:
Nous pourrions même facilement ajouter une cinquième variable en créant une grille de graphiques côte à côte (panneaux) comme suit.
scatterplot +
facet_grid(magFactor ~ region) # ou facet_grid(rows = vars(magFactor), cols = vars(region))
Référence :
facet_grid
:
Les libellés des niveaux d’un facteur peuvent être modifiés ainsi.
# Création d'un vecteur faisant office de « lookup table », contenant l'association entre
# - les niveaux d'un facteur (nom des éléments dans le vecteur) et
# - leurs étiquettes à afficher dans le graphique (éléments du vecteur)
magFactor_labels <- c(
"4" = "mag 4",
"5" = "mag 5",
"6" = "mag 6"
)
# Production du graphique
scatterplot +
facet_grid(
magFactor ~ region,
labeller = labeller(magFactor = magFactor_labels)
)
Références :
La fonction geom_bar
calcule les fréquences des niveaux de facteurs et produit des diagrammes à barres.
ggplot(data = quakes) +
geom_bar(mapping = aes(x = magFactor)) +
labs(x = "classe de magnitude du séisme") +
labs(y = "fréquences")
Si nous avons déjà en main les fréquences, il faut plutôt utiliser la fonction geom_col
pour produire le diagramme en barres.
quakes_mag <- as.data.frame(xtabs(~ magFactor, data = quakes))
str(quakes_mag)
## 'data.frame': 3 obs. of 2 variables:
## $ magFactor: Factor w/ 3 levels "4","5","6": 1 2 3
## $ Freq : int 802 193 5
ggplot(data = quakes_mag) +
geom_col(mapping = aes(x = magFactor, y = Freq)) + # aesthetic y ajoutée
labs(x = "classe de magnitude du séisme") +
labs(y = "fréquences")
Pour obtenir des barres horizontales plutôt que verticales, il faut inverser les deux axes avec coord_flip
.
ggplot(data = quakes) +
geom_bar(mapping = aes(x = magFactor)) +
coord_flip() + # permet d'inverser les axes
labs(x = "classe de magnitude du séisme") +
labs(y = "fréquences")
La fonction geom_text
permet d’ajouter des annotations textuelles dans le graphique.
ggplot(data = quakes, mapping = aes(x = magFactor)) + # aesthetics communs ici
geom_bar() +
geom_text(
mapping = aes(label=stat(count)), # texte ajouté = fréquences
stat = "count", # calcul des fréquences demandé ici
vjust = -0.2 # ajustement vertical
) +
labs(x = "classe de magnitude du séisme") +
labs(y = "fréquences")
Pour représenter des fréquences croisées, on peut ajouter une variable catégorique au graphique via l’argument fill
.
ggplot(data = quakes) +
geom_bar(mapping = aes(x = magFactor, fill = region)) + # aesthetic fill ajoutée
labs(x = "classe de magnitude du séisme") +
labs(y = "fréquences") +
labs(fill = "région")
Pour avoir des bâtons groupés plutôt qu’empilés, il faut modifier la valeur de l’argument position
.
ggplot(data = quakes) +
geom_bar(
mapping = aes(x = magFactor, fill = region),
position = "dodge" # position des bâtons modifiée
) +
labs(x = "classe de magnitude du séisme") +
labs(y = "fréquences") +
labs(fill = "région")
Afin de présenter des fréquences relatives plutôt que brutes.
ggplot(data = quakes) +
geom_bar(
mapping = aes(
x = magFactor,
y = stat(prop), # permet le calcul de fréquences relatives (proportions)
group = region, # pour avoir les fréq. relatives de mag conditionnelles à region
fill = region),
position = "dodge"
) +
labs(title = "Proportions de séismes par classe de magnitude selon la région") +
labs(x = "classe de magnitude du séisme") +
labs(y = "fréquences relatives") +
labs(fill = "région")
Références :
Les auteurs de ggplot2
n’offrent pas de fonction conviviale pour la création de diagrammes en secteurs, probablement parce qu’ils ne recommandent pas leur utilisation. Malgré tout, tenter de tracer un diagramme en secteurs avec ggplot2
aide à comprendre davantage les possibilités du package.
Pour produire un diagramme en secteurs avec ggplot2
, il faut d’abord produire un diagramme à barres empilées, puis demander l’utilisation d’un système de coordonnées polaires par un appel à la fonction coord_polar
.
ggplot(data = quakes) +
geom_bar(mapping = aes(x = 1, fill = magFactor)) +
coord_polar(theta = "y") + # coordonnées polaires
theme_void() + # thème vide
labs(fill = "classe de\nmagnitude")
Pour inverser l’ordre des niveaux d’un facteur, la fonction fct_rev
du package forcats
est pratique.
library(forcats)
ggplot(data = quakes) +
geom_bar(mapping = aes(x = 1, fill = fct_rev(magFactor))) +
coord_polar(theta = "y") +
theme_void() +
labs(fill = "classe de\nmagnitude")
Si la variable n’avait pas été stockée sous forme de facteur, la fonction factor
aurait été utile.
# Créons une copie de quakes, contenant une version numérique de la classe de magnitude
quakes2 <- quakes
quakes2$magFloor <- floor(quakes2$mag)
str(quakes2)
# Production d'un diagramme en secteurs
ggplot(data = quakes2) +
geom_bar(mapping = aes(x = 1, fill = factor(magFloor))) +
coord_polar(theta = "y") +
theme_void() +
labs(fill = "classe de\nmagnitude")
Références :
Il est facile avec ggplot2
de superposer des histogrammes ou des courbes de densités à noyau (comme ci-dessous).
ggplot(data = quakes) +
geom_density(
mapping = aes(x = mag, fill = region),
alpha = 0.5 # niveau d'opacité (0 = transparent, 1 = complètement opaque)
) +
labs(x = "magnitude du séisme") +
labs(y = "densité") +
labs(fill = "région")
Référence :
Un autre outil, dérivé des courbes de densités à noyau, permettant d’explorer l’association potentielle entre une variable numérique et d’une variable catégorique est le violin plot.
violinplots <- ggplot(data = quakes) +
geom_violin(mapping = aes(x = region, y = mag)) +
labs(x = "région") +
labs(y = "magnitude du séisme")
violinplots
Référence :
Le violin plot est en fait d’un mélange entre les courbes de densité à noyau et les diagrammes en boîtes (boxplots).
boxplots <- ggplot(data = quakes) +
geom_boxplot(mapping = aes(x = region, y = mag)) +
labs(x = "région") +
labs(y = "magnitude du séisme")
boxplots
Référence :
Dans le diagramme de dispersion du nombre de stations rapportant le séisme en fonction de la magnitude du séisme (premier exemple), plusieurs points représentent en fait plus d’une observation. Cet overplotting est dû au fait que la variable stations
ne prend que des valeurs entières (il s’agit d’un dénombrement) et la précision de mesure de la variable mag
est limitée au dixième.
Ajouter du jitter à des observations signifie de leur ajouter de petites quantités aléatoires, parfois appelées du bruit blanc.
ggplot(data = quakes) +
geom_jitter( # geom_jitter est utilisé au lieu de geom_point
mapping = aes(x = mag, y = stations),
colour = "blue",
alpha = 0.3
) +
labs(title = "1000 séismes près de Fiji") +
labs(x = "magnitude du séisme") +
labs(y = "nombre de stations rapportant le séisme")
Référence :
geom_jitter
:
ggplot(
data = quakes,
mapping = aes(x = mag, y = stations) # aesthetics communs placées ici
) +
stat_density_2d( # ajout de l'estimation de densité 2D
aes(fill = stat(density)),
geom = "tile",
contour = FALSE
) +
geom_point(
shape = 20, # pour modifier le symbole des points
colour = "dodgerblue4"
) +
labs(title = "1000 séismes près de Fiji") +
labs(x = "magnitude du séisme") +
labs(y = "nombre de stations rapportant le séisme") +
labs(fill = "densité") +
scale_fill_continuous( # pour modifier l'échelle de couleur
low = "white",
high = "dodgerblue3"
) +
theme_classic() # pour avoir rapidement un fond blanc
Références :
D’autres solutions sont proposées ici : https://ggplot2.tidyverse.org/reference/geom_point.html#overplotting
# Statistique dont on aura besoin
moy <- mean(quakes$mag)
et <- sd(quakes$mag)
ggplot(data = quakes, mapping = aes(x = mag)) +
geom_histogram(
mapping = aes(y = stat(density)),
binwidth = 0.1,
colour = "black",
fill = "white"
) +
labs("Densité empirique des magnitudes dans le jeu de données quakes") +
labs(x = "magnitude du séisme") +
labs(y = "densité") +
stat_function( # ajout d'une courbe de densité normale
fun = dnorm,
args = list(mean = moy, sd = et), # avec paramètres estimés à partir des données
xlim = c(3.95, 6.45)
)
Référence :
ggplot(data = quakes, mapping = aes(x = mag)) +
geom_histogram(
mapping = aes(y = stat(density)),
binwidth = 0.1,
colour = "black",
fill = "white"
) +
labs("Densité empirique des magnitudes dans le jeu de données quakes") +
labs(x = "magnitude du séisme") +
labs(y = "densité") +
geom_density(
aes(colour = "Densité à noyau"),
) +
stat_function(
aes(colour = "Densité normale"),
fun = dnorm,
args = list(mean = moy, sd = et),
xlim = c(3.95, 6.45)
) +
scale_colour_manual(
name = "",
values = c("blue", "red"),
labels = c("Densité à noyau", "Densité normale")
)
Référence :
ggplot(data = quakes) +
geom_bar(
mapping = aes(
x = magFactor,
y = stat(prop), # permet le calcul de fréquences relatives (proportions)
group = region, # pour avoir les fréq. relatives de mag conditionnelles à region
fill = region),
position = "dodge"
) +
labs(title = "Proportions de séismes par classe de magnitude selon la région") +
labs(x = "classe de magnitude du séisme") +
labs(y = "fréquences relatives") +
labs(fill = "région") +
theme(
legend.position="top",
legend.background = element_rect(size=0.5, linetype="solid", colour ="black")
)
Références :
ggplot2
et extensions de ggplot2
library(dplyr)
Situation courante : vouloir produire un graphique à partir d’un sous-ensemble des données plutôt qu’avec le jeu de données complet. Il est alors pratique d’utiliser l’opérateur %>%
et la fonction filter
de dplyr
comme suit :
quakes %>%
filter(region == "Ouest") %>%
ggplot(mapping = aes(x = mag, y = stations)) +
geom_jitter(colour = "blue", alpha = 0.3) +
labs(x = "magnitude du séisme") +
labs(y = "nombre de stations rapportant le séisme")
ggplot2
ggthemes
library(ggthemes)
scatterplot +
theme_economist()
scatterplot +
theme_excel()
Référence :
cowplot
library(cowplot)
plot_grid(
violinplots + ggtitle("Violin plots"),
boxplots + ggtitle("Boxplots")
)
title <- ggdraw() + draw_label("Lesquels préférez-vous ?", fontface='bold')
plot_grid(
title,
plot_grid(
violinplots + ggtitle("Violin plots"),
boxplots + ggtitle("Boxplots")
),
ncol=1, rel_heights=c(0.1, 1)
)
detach("package:cowplot", unload=TRUE)
Référence :
ggExtra
library(ggExtra)
ggMarginal(scatterplot, type = "histogram")
Référence :
ggiraph
library(ggiraph)
g <- ggplot(quakes, aes(x = long, y = lat, color = depth)) +
coord_quickmap() # coord_quickmap() permet d'avoir des axes sur la même échelle
my_gg <- g +
geom_point_interactive(
mapping = aes(tooltip = stations),
size = 2
)
ggiraph(code = print(my_gg),
tooltip_extra_css = "background-color:gray;color:white;font-style:italic;padding:10px;border-radius:10px 20px 10px 20px;",
tooltip_opacity = 0.75)
Référence :
maps
library(maps)
monde <- map_data("world") # va chercher des données provenant du package maps ou mapdata
ggplot() +
geom_polygon(
data = monde,
aes(x = long, y = lat, group = group),
fill = "gray90",
col = "black"
) +
geom_point(
data = quakes,
aes(x = long, y = lat, colour = region),
alpha = .3
) +
coord_fixed(
xlim = c(115, 190),
ylim = c(-50, 0),
ratio = 1.3
) +
labs(x = "longitude", y = "latitude", colour = "région") +
theme_bw()
Référence :