Visualisation de données
Last updated on 2025-05-05 | Edit this page
Estimated time: 120 minutes
Overview
Questions
- Visualisation en R
Objectives
- Produire des scatter plots (nuages de points), des boxplots (boîtes à moustache), des line plots (tracés linéaires), etc. en utilisant ggplot.
- Définir les paramètres universels des graphiques.
- Décrire ce qu’est le faceting (facettage) et appliquez le faceting dans ggplot.
- Modifiez les éléments esthétiques d’un tracé
ggplot
existant (y compris les étiquettes et la couleur des axes). - Créer des graphiques complexes et personnalisés à prtir de données dans un data frame.
Cet épisode est basé sur la leçon Data Analysis and Visualisation in R for Ecologists des Data Carpentries.
Visualisation de données
Nous commençons par charger les packages requis.
ggplot2
est inclus dans le package
tidyverse
.
R
bibliothèque("tidyverse")
ERROR
Error in bibliothèque("tidyverse"): could not find function "bibliothèque"
Si vous n’êtes pas encore dans l’espace de travail, chargez les données que nous avons enregistrées dans la leçon précédente.
R
arn <- read.csv("data/rnaseq.csv")
La Data Visualization Cheat
couvrira les bases et les fonctionnalités plus avancées de
ggplot2
et servira non seulement de pense-bête, mais
donnera aussi un aperçu des nombreuses représentations de données
disponibles dans le package. Les didacticiels vidéo suivants (partie 1 et 2) de Thomas
Lin Pedersen sont également très instructifs.
Tracer avec ggplot2
ggplot2
est un package graphique qui simplifie la
création de graphiques complexes à partir de données dans un data
frame. Il fournit une interface de programmation pour spécifier les
variables à représenter sur le graphique, comment elles sont
représentées, ainsi que les propriétés visuelles générales. Les concepts
théoriques qui sont à la base de ggplot2
sont décrits dans
le livre Grammar of Graphics (@Wilkinson :2005). En utilisant cette approche ,
nous n’avons besoin que de changements minimes si les données
sous-jacentes changent ou si nous décidons de passer d’un bar
plot à un scatter plot, par exemple. Cela aide à créer des
graphiques de qualité professionnelle avec un minimum d’ajustements.
Il existe aussi un livre décrivant ggplot2
(@ggplot2book) qui en fournit un bon aperçu, mais
il est obsolète. La 3ème édition est en préparation et sera disponible gratuitement en ligne.
La page Web ggplot2
(https://ggplot2.tidyverse.org)
fournit une documentation abondante.
ggplot2
fonctionne avec des données au format « long »,
c’est-à-dire une colonne pour chaque variable et une ligne pour chaque
observation. Des données bien structurées vous feront gagner beaucoup de
temps lors de la création de figures avec ggplot2
.
Les graphiques ggplot sont construits étape par étape en ajoutant de nouveaux éléments appelés couches. L’ajout progressif de couches permet une grande flexibilité et une personnalisation des graphiques.
L’idée derrière la “Grammar of Graphics” est que vous pouvez construire chaque graphique à partir des 3 mêmes composants : (1) un jeu de données, (2) un système de coordonnées, et (3) des “geoms” — c’est-à-dire des marques visuelles qui représentent des points de données [^trois\_comp\_ggplot2]
Pour construire un ggplot, nous utiliserons le modèle de base suivant qui peut être utilisé pour différents types de graphiques :
ggplot(data = <DATA>, mapping = aes(<MAPPINGS>)) + <GEOM_FUNCTION>()
- utiliser la fonction
ggplot()
et lier un data frame spécifique en utilisant l’argumentdata
R
ggplot(data = rna)
- définir un mapping (en utilisant la fonction
d’esthétique (
aes
)), qui consiste à: (1) sélectionner les variables du data frame à réprésenter et (2) les lier à des caractéristiques du graphique comme les coordonnées x ou y, ou encore la taille, la couleur, la forme, etc.
R
ggplot(data = rna, mapping = aes(x = expression))
- ajouter des ‘geoms’ - géométries ou représentations
graphiques des données dans le graphique (points, lignes, barres).
ggplot2
propose de nombreux geom différents. Ici nous utiliserons les plus courantes, par exemple :
* `geom_point()` pour les *scatter plots* (nuages de points), les *dot plots* (diagrammes de points), etc.
* `geom_histogram()` pour les histogrammes
* `geom_boxplot()` pour, eh bien, les *boxplots* !
* `geom_line()` pour les lignes de tendance, les séries chronologiques, etc.
Pour ajouter un geom au graphique, utilisez l’opérateur
+
. Utilisons d’abord geom_histogram()
:
R
ggplot(data = rna, mapping = aes(x = expression)) +
geom_histogram()
ERROR
Error in ggplot(data = rna, mapping = aes(x = expression)): could not find function "ggplot"
Le symbole +
dans le package ggplot2
est
particulièrement utile car il vous permet de modifier les objets
ggplot
existants. Cela signifie que vous pouvez facilement
configurer des modèles de graphique et explorer facilement différents
types de graphiques. En procédant de la sorte, le graphique obtenu
précédemment peut également être généré avec un code comme
celui-ci :
R
# Assign plot to a variable
rna_plot <- ggplot(data = rna,
mapping = aes(x = expression))
# Draw the plot
rna_plot + geom_histogram()
Défi
Vous avez probablement remarqué un message automatique qui apparaît lorsqu’on trace un histogramme :
ERROR
Error in ggplot(rna, aes(x = expression)): could not find function "ggplot"
Définissez un mapping (en utilisant la fonction esthétique
(aes
)), qui consiste à: (1) sélectionner les variables du
data frame à réprésenter et (2) les lier à des caractéristiques
du graphique comme les coordonnées x ou y, ou encore la taille, la
couleur, la forme, etc.
R
# change bins
ggplot(rna, aes(x = expression)) +
geom_histogram(bins = 15)
ERROR
Error in ggplot(rna, aes(x = expression)): could not find function "ggplot"
R
# change binwidth
ggplot(rna, aes(x = expression)) +
geom_histogram(binwidth = 2000)
ERROR
Error in ggplot(rna, aes(x = expression)): could not find function "ggplot"
Nous pouvons observer ici que les données présentent un right
skew (asymétrie vers la droite). Nous pouvons appliquer la
transformation log2 pour obtenir une distribution plus symétrique. Notez
que nous ajoutons ici une petite valeur constante (+1
) pour
éviter que -Inf
soit renvoyée pour des expressions égales à
0.
R
arn <- arn %>%
muter(expression_log = log2(expression + 1))
ERROR
Error in arn %>% muter(expression_log = log2(expression + 1)): could not find function "%>%"
Si l’on dessine maintenant l’histogramme des expressions transformées en log2, la distribution est en effet plus proche d’une distribution normale.
R
ggplot(rna, aes(x = expression_log)) + geom_histogram()
ERROR
Error in ggplot(rna, aes(x = expression_log)): could not find function "ggplot"
À partir de maintenant, nous travaillerons sur les valeurs d’expression transformées en log.
Défi
Une autre façon de visualiser cette transformation, plutôt que de transformer les données elles-mêmes, est de garder les données inchangées mais de choisir une autre échelle des observations. Par exemple, il peut être intéressant de changer l’échelle de l’axe pour mieux répartir les observations dans le graphique. Changer l’échelle des axes se fait de la même manière que pour ajouter/modifier d’autres composants (c’est-à-dire en ajoutant progressivement des commandes). Essayez de modifier le graphique précédent de la manière suivante:
- Représenter l’expression non transformée sur l’échelle log10 ; voir
scale_x_log10()
. Comparer le résultat avec le graphique précédent. Pourquoi des warnings (messages d’avertissement) apparaissent-ils maintenant ?
R
ggplot(data = rna,mapping = aes(x = expression))+
geom_histogram() +
scale_x_log10()
ERROR
Error in ggplot(data = rna, mapping = aes(x = expression)): could not find function "ggplot"
Remarques
- Tout ce que vous mentionnez dans la fonction
ggplot()
peut être vu par n’importe quelle couche geom que vous ajoutez par la suite (c’est-à-dire qu’il s’agit de paramètres de graphiques globaux). Ceci y compris le mapping des axes x et y que vous avez configuré dansaes()
. - Vous pouvez également spécifier des mappings pour un geom
donné, indépendamment des mappings définis globalement dans la fonction
ggplot()
. - Le signe
+
, utilisé pour ajouter de nouvelles couches, doit être placé à la fin de la ligne contenant la couche précédente. Si , au contraire, le signe+
est ajouté au début d’une ligne contenant la nouvelle couche,ggplot2
n’ajoutera pas la nouvelle couche et retournera un message d’erreur.
R
# This is the correct syntax for adding layers
rna_plot +
geom_histogram()
# This will not add the new layer and will return an error message
rna_plot
+ geom_histogram()
Construire vos graphiques de manière itérative
Nous allons maintenant dessiner un scatter plot avec deux
variables continues et la fonction geom_point()
. Ce
graphique représentera les log2 fold changes
(ratio de
valeurs convertis en log
) des expressions, entre le temps 8
et le temps 0 d’une part, et entre le temps 4 et le temps 0 d’autre
part. Pour ce faire, nous devons d’abord calculer les moyennes des
valeurs d’expression transformées en log par gène et par temps, puis les
log fold changes souhaités. Notez que nous incluons également
ici le biotype du gène, que nous utiliserons plus tard pour représenter
les gènes. Nous enregistrerons les log fold changes dans un
nouveau data frame appelé rna_fc.
R
rna_fc <- rna %>% select(gene, time,
gene_biotype, expression_log) %>%
group_by(gene, time, gene_biotype) %>%
summary(mean_exp = moyenne (expression_log)) %>%
pivot_wider(names_from = temps,
valeurs_from = moyenne_exp) %>%
mutate(time_8_vs_0 = `8` - `0`, time_4_vs_0 = `4` - `0`)
ERROR
Error in rna %>% select(gene, time, gene_biotype, expression_log) %>% : could not find function "%>%"
Nous pouvons ensuite construire un ggplot avec le jeu de données
nouvellement créé rna_fc
. Construire des graphiques avec
ggplot2
est généralement un processus itératif. Nous
commençons par définir le jeu de données que nous allons utiliser,
tracer les axes et choisir une geom :
R
ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0)) +
geom_point()
ERROR
Error in ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0)): could not find function "ggplot"
Ensuite, nous commençons à modifier ce graphique pour en extraire davantage d’informations. Par exemple, nous pouvons ajouter de la transparence (« alpha ») pour éviter la surcharge du graphique:
R
ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0)) +
geom_point(alpha = 0.3)
ERROR
Error in ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0)): could not find function "ggplot"
On peut également ajouter des couleurs pour tous les points :
R
ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0)) +
geom_point(alpha = 0.3, color = "blue")
ERROR
Error in ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0)): could not find function "ggplot"
Ou pour colorer différemment chaque gène du graphique, vous pouvez
utiliser un vecteur comme input dans l’argument color.
ggplot2
assignera une couleur différente à chaques valeurs
dans le vecteur. Voici un exemple où nous colorons avec la variable
gene_biotype
:
R
ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0)) +
geom_point(alpha = 0.3, aes(color = gene_biotype))
ERROR
Error in ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0)): could not find function "ggplot"
Nous pouvons également spécifier les couleurs directement à
l’intérieur du mapping fourni dans la fonction ggplot()
.
Cela sera visible par toutes les couches de geom et le mapping
sera déterminé par les axes x et y définis dans aes()
.
R
ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0,
color = gene_biotype)) +
geom_point(alpha = 0.3)
ERROR
Error in ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0, : could not find function "ggplot"
Enfin, nous pourrions également ajouter une ligne diagonale avec la
fonction geom_abline()
:
R
ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0,
color = gene_biotype)) +
geom_point(alpha = 0.3) +
geom_abline(intercept = 0)
ERROR
Error in ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0, : could not find function "ggplot"
Notez que nous pouvons remplacer geom_point
par
geom_jitter
et les couleurs seront toujours déterminées par
gene_biotype
.
R
ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0,
color = gene_biotype)) +
geom_jitter(alpha = 0.3) +
geom_abline(intercept = 0)
ERROR
Error in ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0, : could not find function "ggplot"
ERROR
Error in bibliothèque("hexbin"): could not find function "bibliothèque"
Défi
Les scatter plots peuvent être des outils d’exploration
utiles pour de petits jeux de données. Pour les jeux de données avec un
grand nombre d’observations, tels que le jeu de données
rna_fc
, l’accumulation de points peut surcharger le
graphique, ce qui constitue une limitation des scatter plots.
Une stratégie possible dans de tels cas consiste à utiliser le
regroupement hexagonal d’observations. Dans ce cas, l’espace du
graphique est divisé en hexagones. Chaque hexagone se voit attribuer une
couleur en fonction du nombre d’observations qui se trouvent à
l’intérieur.
Pour utiliser le regroupement hexagonal dans
ggplot2
, installez d’abord le package Rhexbin
depuis CRAN et chargez-le.Utilisez ensuite la fonction
geom_hex()
pour produire la figure hexbin.Quelles sont les avantages et inconvénients d’un diagramme hexagonal, par rapport à un scatter plot ? Examinez le scatter plot ci-dessus et comparez-le avec le diagramme hexagonal que vous avez créé.
R
install.packages("hexbin")
R
library("hexbin")
ERROR
Error in library("hexbin"): there is no package called 'hexbin'
R
ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0)) +
geom_hex() +
geom_abline(intercept = 0)
ERROR
Error in ggplot(data = rna_fc, mapping = aes(x = time_4_vs_0, y = time_8_vs_0)): could not find function "ggplot"
Défi
Utilisez ce que vous venez d’apprendre pour créer un scatter
plot de la variable expression_log
en fonction de la
variable sample
, à partir du jeu de données
rna
, avec l’heure affichée dans différentes couleurs.
Est-ce une bonne façon d’afficher ce type de données ?
R
ggplot(data = rna, mapping = aes(y = expression_log, x = sample)) +
geom_point(aes(color = time))
ERROR
Error in ggplot(data = rna, mapping = aes(y = expression_log, x = sample)): could not find function "ggplot"
Boxplot (boîte à moustaches)
Nous pouvons utiliser des boxplots pour visualiser la distribution des expressions géniques au sein de chaque échantillon :
R
ggplot(data = rna,
mapping = aes(y = expression_log, x = sample)) +
geom_boxplot()
ERROR
Error in ggplot(data = rna, mapping = aes(y = expression_log, x = sample)): could not find function "ggplot"
En ajoutant des points au boxplot, on peut avoir une meilleure idée du nombre de mesures et de leur distribution :
R
ggplot(data = rna,
mapping = aes(y = expression_log, x = sample)) +
geom_jitter(alpha = 0.2, color = "tomato") +
geom_boxplot(alpha = 0)
ERROR
Error in ggplot(data = rna, mapping = aes(y = expression_log, x = sample)): could not find function "ggplot"
Défi
Avez-vous remarqué que la couche boxplot se trouve devant la couche jitter ? Que devez-vous modifier dans le code pour placer le boxplot sous les points ?
Nous devrions inverser l’ordre de ces deux geom:
R
ggplot(data = rna,
mapping = aes(y = expression_log, x = sample)) +
geom_boxplot(alpha = 0) +
geom_jitter(alpha = 0.2, color = "tomato")
ERROR
Error in ggplot(data = rna, mapping = aes(y = expression_log, x = sample)): could not find function "ggplot"
Vous remarquerez peut-être que les valeurs sur l’axe des x ne sont toujours pas lisibles correctement. Modifions l’orientation des étiquettes et ajustons-les verticalement et horizontalement afin qu’elles ne se chvauchent pas. Vous pouvez utiliser un angle de 90 degrés ou expérimenter pour trouver l’angle approprié pour des étiquettes orientées en diagonale :
R
ggplot(data = rna,
mapping = aes(y = expression_log, x = sample)) +
geom_jitter(alpha = 0.2, color = "tomato") +
geom_boxplot(alpha = 0) +
theme(axis.text.x = element_text(angle = 90, hjust = 0.5, vjust = 0.5))
ERROR
Error in ggplot(data = rna, mapping = aes(y = expression_log, x = sample)): could not find function "ggplot"
Défi
Ajoutez de la couleur aux points de données sur votre boxplot en fonction de la durée de l’infection (« time »).
Indice : Vérifiez la classe pour la variable time.
Envisagez de changer la classe de time
d’entier à
factor directement dans le mapping ggplot. Pourquoi cela
change-t-il la façon dont R crée le graphique ?
R
# time as integer
ggplot(data = rna,
mapping = aes(y = expression_log,
x = sample)) +
geom_jitter(alpha = 0.2, aes(color = time)) +
geom_boxplot(alpha = 0) +
theme(axis.text.x = element_text(angle = 90, hjust = 0.5, vjust = 0.5))
ERROR
Error in ggplot(data = rna, mapping = aes(y = expression_log, x = sample)): could not find function "ggplot"
R
# time as factor
ggplot(data = rna,
mapping = aes(y = expression_log,
x = sample)) +
geom_jitter(alpha = 0.2, aes(color = as.factor(time))) +
geom_boxplot(alpha = 0) +
theme(axis.text.x = element_text(angle = 90, hjust = 0.5, vjust = 0.5))
ERROR
Error in ggplot(data = rna, mapping = aes(y = expression_log, x = sample)): could not find function "ggplot"
Défi
Les boxplots sont des résumés utiles, mais ils ne révèlent pas la forme de la distribution. Par exemple, si la distribution est bi-modale, nous ne le verrions pas dans un boxplot. Une alternative au boxplot est le violin plot (graphiques en violon) , où la forme de la densité de points est dessinée.
- Remplacez la box plot par un violin plot ; voir
geom_violin()
. Liez la couleur de remplissage des violons à la variabletime
, grâce à l’argumentfill
.
R
ggplot(data = rna,
mapping = aes(y = expression_log, x = sample)) +
geom_violin(aes(fill = as.factor(time))) +
theme(axis.text.x = element_text(angle = 90, hjust = 0.5, vjust = 0.5))
ERROR
Error in ggplot(data = rna, mapping = aes(y = expression_log, x = sample)): could not find function "ggplot"
Défi
- Modifiez le violin plot pour lier la couleur de remplissage des violons à la variable “sex”.
R
ggplot(data = rna,
mapping = aes(y = expression_log, x = sample)) +
geom_violin(aes(fill = sex)) +
theme(axis.text.x = element_text(angle = 90, hjust = 0.5, vjust = 0.5))
ERROR
Error in ggplot(data = rna, mapping = aes(y = expression_log, x = sample)): could not find function "ggplot"
Line plots (graphiques linéaires)
Calculons l’expression moyenne par durée de l’infection pour les 10
gènes ayant les log fold changes comparant le temps 8 au temps
0 les plus élevés. Tout d’abord, nous devons sélectionner les gènes et
créer un sous-ensemble de rna
appelé sub_rna
contenant les 10 gènes sélectionnés, puis nous devons regrouper les
données et calculer l’expression moyenne des gènes dans chaque groupe
:
R
rna_fc <- rna_fc |> arrange(desc(time_8_vs_0))
ERROR
Error in arrange(rna_fc, desc(time_8_vs_0)): could not find function "arrange"
R
genes_selected <- rna_fc$gene[1:10]
ERROR
Error: object 'rna_fc' not found
R
sub_rna <- rna |>
filter(gene %in% genes_selected)
ERROR
Error: object 'rna' not found
R
mean_exp_by_time <- sub_rna |>
group_by(gene,time) |>
summarize(mean_exp = mean(expression_log))
ERROR
Error in summarize(group_by(sub_rna, gene, time), mean_exp = mean(expression_log)): could not find function "summarize"
R
mean_exp_by_time
ERROR
Error: object 'mean_exp_by_time' not found
Nous pouvons construire le line plot avec la durée de l’infection sur l’axe des x et l’expression moyenne sur l’axe des y :
R
ggplot(data = moyenne_exp_by_time, mapping = aes(x = temps, y = moyenne_exp)) +
geom_line()
ERROR
Error in ggplot(data = moyenne_exp_by_time, mapping = aes(x = temps, y = moyenne_exp)): could not find function "ggplot"
Malheureusement, cela ne fonctionne pas car nous avons représenté
ensemble les données de tous les gènes . Nous devons dire à ggplot de
tracer une ligne pour chaque gène en modifiant la fonction esthétique
pour inclure group = gene
:
R
ggplot(data = moyenne_exp_by_time,
mapping = aes(x = temps, y = moyenne_exp, groupe = gène)) +
geom_line()
ERROR
Error in ggplot(data = moyenne_exp_by_time, mapping = aes(x = temps, y = moyenne_exp, : could not find function "ggplot"
Nous pourrons distinguer les gènes dans le graphique si nous ajoutons
des couleurs (l’utilisation de color
regroupe également
automatiquement les données) :
R
ggplot(data = moyenne_exp_by_time,
mapping = aes(x = temps, y = moyenne_exp, couleur = gène)) +
geom_line()
ERROR
Error in ggplot(data = moyenne_exp_by_time, mapping = aes(x = temps, y = moyenne_exp, : could not find function "ggplot"
Faceting (diviser en facettes)
ggplot2
a une technique spéciale appelée
faceting qui permet à l’utilisateur de diviser un graphique en
plusieurs (sous) graphiques en fonction d’un facteur inclus dans le jeu
de données. Ces différents sous-graphiques héritent des mêmes propriétés
(limites des axes, graduations, …) pour faciliter leur comparaison
directe. Nous allons l’utiliser pour créer un line plot en
fonction du temps pour chaque gène :
R
ggplot(data = moyenne_exp_by_time,
mapping = aes(x = temps, y = moyenne_exp)) + geom_line() +
facet_wrap(~ gène)
ERROR
Error in ggplot(data = moyenne_exp_by_time, mapping = aes(x = temps, y = moyenne_exp)): could not find function "ggplot"
Ici, les axes x et y ont la même échelle pour tous les
sous-graphiques. Vous pouvez changer ce comportement par défaut en
modifiant scales
afin d’autoriser une échelle libre pour
l’axe y :
R
ggplot(data = moyenne_exp_by_time,
mapping = aes(x = temps, y = moyenne_exp)) +
geom_line() +
facet_wrap(~ gene, scales = "free_y")
ERROR
Error in ggplot(data = moyenne_exp_by_time, mapping = aes(x = temps, y = moyenne_exp)): could not find function "ggplot"
Nous aimerions maintenant diviser la ligne dans chaque graphiques selon le sexe des souris. Pour ce faire, nous devons calculer l’expression moyenne dans le data frame regroupé par “gene”, “time” et “sex” :
R
Mean_exp_by_time_sex <- sub_rna %>%
group_by(gene, time, sex) %>%
summary(mean_exp = Mean(expression_log))
ERROR
Error in sub_rna %>% group_by(gene, time, sex) %>% summary(mean_exp = Mean(expression_log)): could not find function "%>%"
R
Mean_exp_by_time_sex
ERROR
Error: object 'Mean_exp_by_time_sex' not found
Nous pouvons maintenant créer le graphique à facettes. Nous ajoutons encore de l’information en divisant le line plot par sexe en y associant des couleurs (au sein d’un seul graphique) :
R
ggplot(data = moyenne_exp_by_time_sex,
mapping = aes(x = temps, y = moyenne_exp, couleur = sexe)) +
geom_line() +
facet_wrap(~ gène, échelles = "free_y")
ERROR
Error in ggplot(data = moyenne_exp_by_time_sex, mapping = aes(x = temps, : could not find function "ggplot"
Généralement, les graphiques sur fond blanc sont plus lisibles une
fois imprimés. Nous pouvons définir l’arrière-plan en blanc en utilisant
la fonction theme_bw()
. De plus, nous pouvons supprimer la
grille :
R
ggplot(data = moyenne_exp_by_time_sex,
mapping = aes(x = temps, y = moyenne_exp, couleur = sexe)) +
geom_line() +
facet_wrap(~ gène, échelles = "free_y") +
theme_bw() +
theme(panel.grid = element_blank())
ERROR
Error in ggplot(data = moyenne_exp_by_time_sex, mapping = aes(x = temps, : could not find function "ggplot"
Défi
Utilisez ce que vous venez d’apprendre pour créer un graphique illustrant comment l’expression moyenne de chaque chromosome change au cours de la durée de l’infection .
R
Mean_exp_by_chromosome <- rna %>%
group_by(chromosome_name, time) %>%
summary(mean_exp = Mean(expression_log))
ERROR
Error in rna %>% group_by(chromosome_name, time) %>% summary(mean_exp = Mean(expression_log)): could not find function "%>%"
R
ggplot(data = Mean_exp_by_chromosome, mapping = aes( x = temps,
y = moyenne_exp)) +
geom_line() +
facet_wrap(~ chromosome_name, scales = "free_y")
ERROR
Error in ggplot(data = Mean_exp_by_chromosome, mapping = aes(x = temps, : could not find function "ggplot"
Le geom facet_wrap
extrait les graphiques dans
un nombre quelconque de dimensions pour leur permettre de s’adapter
joliment à une seule page. De plus, le geom
facet_grid
permet de spécifier explicitement comment les
graphiques doivent être disposés par la notation en formule
(rows ~ columns
; un .
peut-être utilisé comme
un raccourci pour indiquer une seule ligne ou colonne).
Modifions le graphique précédent pour comparer l’évolution de l’expression génétique moyenne des hommes et des femmes au fil du temps :
R
# Une colonne, facette par lignes
ggplot(data = Mean_exp_by_time_sex,
mapping = aes(x = time, y = Mean_exp, color = gene)) +
geom_line() +
facet_grid(sexe ~ .)
ERROR
Error in ggplot(data = Mean_exp_by_time_sex, mapping = aes(x = time, y = Mean_exp, : could not find function "ggplot"
R
# Une ligne, facette par colonne
ggplot(data = Mean_exp_by_time_sex,
mapping = aes(x = time, y = Mean_exp, color = gene)) +
geom_line() +
facet_grid(. ~ sexe)
ERROR
Error in ggplot(data = Mean_exp_by_time_sex, mapping = aes(x = time, y = Mean_exp, : could not find function "ggplot"
Thèmes ggplot2
En plus de theme_bw()
, qui change l’arrière-plan du
graphique en blanc, ggplot2
contient plusieurs autres
thèmes qui peuvent être utiles pour changer rapidement l’apparence de
votre visualisation. La liste complète des thèmes est disponible sur https://ggplot2.tidyverse.org/reference/ggtheme.html.
theme_minimal()
et theme_light()
sont
populaires, et theme_void()
peut être utile comme point de
départ pour créer un nouveau thème à la main.
Le package ggthemes
fournit une grande variété d’options (y compris un thème Excel 2003 ).
Le site internet des
extensions ggplot2
met à disposition une collection de
packages permettant d’étendre les fonctionnalités de
ggplot2
, y compris des thèmes supplémentaires.
Personnalisation
Revenons au graphique à facettes de l’expression moyenne par temps et gène, colorée par sexe.
Consultez la ggplot2, et réfléchissez aux améliorations possibles à apporter à votre graphique.
Maintenant, nous pouvons changer les noms des axes en quelque chose de plus informatif que ‘time’ et ‘mean_exp’, et ajouter un titre à la figure :
R
ggplot(data = moyenne_exp_by_time_sex,
mapping = aes(x = temps, y = moyenne_exp, couleur = sexe)) +
geom_line() +
facet_wrap(~ gène, échelles = "free_y") +
theme_bw() +
theme(panel.grid = element_blank()) +
labs(title = "Expression moyenne des gènes selon la durée de l'infection",
x = "Durée de l'infection (en jours)",
y = "Expression moyenne des gènes")
ERROR
Error in ggplot(data = moyenne_exp_by_time_sex, mapping = aes(x = temps, : could not find function "ggplot"
Les axes ont des noms plus informatifs, mais leur lisibilité peut être améliorée en augmentant la taille de la police :
R
ggplot(data = moyenne_exp_by_time_sex,
mapping = aes(x = temps, y = moyenne_exp, couleur = sexe)) +
geom_line() +
facet_wrap(~ gène, échelles = "free_y") +
theme_bw() +
theme(panel.grid = element_blank()) +
labs(title = "Expression moyenne des gènes selon la durée de l'infection",
x = "Durée de l'infection (en jours)",
y = "Expression génétique moyenne") +
theme(text = element_text(size = 16))
ERROR
Error in ggplot(data = moyenne_exp_by_time_sex, mapping = aes(x = temps, : could not find function "ggplot"
Notez qu’il est également possible de changer les polices de vos
graphiques. Si vous êtes sous Windows, vous devrez peut-être installer
le package
extrafont
.
Nous pouvons personnaliser davantage la couleur du texte des axes x
et y, la couleur de la grille, etc. Nous pouvons aussi par exemple
déplacer la légende vers le haut en mettant legend.position
égal à "top"
.
R
ggplot(data = mean_exp_by_time_sex,
mapping = aes(x = time, y = mean_exp, color = sex)) +
geom_line() +
facet_wrap(~ gene, scales = "free_y") +
theme_bw() +
theme(panel.grid = element_blank()) +
labs(title = "Mean gene expression by duration of the infection",
x = "Duration of the infection (in days)",
y = "Mean gene expression") +
theme(text = element_text(size = 16),
axis.text.x = element_text(colour = "royalblue4", size = 12),
axis.text.y = element_text(colour = "royalblue4", size = 12),
panel.grid = element_line(colour="lightsteelblue1"),
legend.position = "top")
ERROR
Error in ggplot(data = mean_exp_by_time_sex, mapping = aes(x = time, y = mean_exp, : could not find function "ggplot"
Si vous aimez les modifications que vous avez créées au thème par défaut, vous pouvez les enregistrer en tant qu’objet pour pouvoir les appliquer facilement à d’autres graphiques par la suite. Voici un exemple avec l’histogramme que nous avons créé précédemment.
R
blue_theme <- theme(axis.text.x = element_text(colour = "royalblue4",
size = 12),
axis.text.y = element_text(colour = "royalblue4",
size = 12),
text = element_text(size = 16),
panel.grid = element_line(colour="lightsteelblue1"))
ERROR
Error in theme(axis.text.x = element_text(colour = "royalblue4", size = 12), : could not find function "theme"
R
ggplot(rna, aes(x = expression_log)) +
geom_histogram(bins = 20) +
blue_theme
ERROR
Error in ggplot(rna, aes(x = expression_log)): could not find function "ggplot"
Défi
Considérant toutes ces nouvelles informations, pourriez-vous consacrer encore cinq minutes, soit pour améliorer l’un des graphiques générés dans cet exercice, soit pour créer votre propre graphique ? Utilisez la RStudio ggplot2 pour vous en inspirer. Voici quelques idées :
- Voyez si vous pouvez modifier l’épaisseur des lignes.
- Pouvez-vous trouver un moyen de changer le nom de la légende ? Qu’en
est-il de ses labels ? (indice : recherchez une fonction ggplot
commençant par
scale_
) - Essayez d’utiliser une palette de couleurs différente ou de spécifier manuellement les couleurs pour les lignes (voir http://www.cookbook-r.com/Graphs/Colors_(ggplot2)/).
Par exemple, sur la base de ce graphique :
R
ggplot(data = moyenne_exp_by_time_sex,
mapping = aes(x = temps, y = moyenne_exp, couleur = sexe)) +
geom_line() +
facet_wrap(~ gène, échelles = "free_y") +
theme_bw() +
theme(panel.grid = element_blank())
ERROR
Error in ggplot(data = moyenne_exp_by_time_sex, mapping = aes(x = temps, : could not find function "ggplot"
Nous pouvons le personnaliser des manières suivantes :
R
# change the thickness of the lines
ggplot(data = mean_exp_by_time_sex,
mapping = aes(x = time, y = mean_exp, color = sex)) +
geom_line(size=1.5) +
facet_wrap(~ gene, scales = "free_y") +
theme_bw() +
theme(panel.grid = element_blank())
ERROR
Error in ggplot(data = mean_exp_by_time_sex, mapping = aes(x = time, y = mean_exp, : could not find function "ggplot"
R
# change the name of the legend and the labels
ggplot(data = mean_exp_by_time_sex,
mapping = aes(x = time, y = mean_exp, color = sex)) +
geom_line() +
facet_wrap(~ gene, scales = "free_y") +
theme_bw() +
theme(panel.grid = element_blank()) +
scale_color_discrete(name = "Gender", labels = c("F", "M"))
ERROR
Error in ggplot(data = mean_exp_by_time_sex, mapping = aes(x = time, y = mean_exp, : could not find function "ggplot"
R
# using a different color palette
ggplot(data = mean_exp_by_time_sex,
mapping = aes(x = time, y = mean_exp, color = sex)) +
geom_line() +
facet_wrap(~ gene, scales = "free_y") +
theme_bw() +
theme(panel.grid = element_blank()) +
scale_color_brewer(name = "Gender", labels = c("F", "M"), palette = "Dark2")
ERROR
Error in ggplot(data = mean_exp_by_time_sex, mapping = aes(x = time, y = mean_exp, : could not find function "ggplot"
R
# manually specifying the colors
ggplot(data = mean_exp_by_time_sex,
mapping = aes(x = time, y = mean_exp, color = sex)) +
geom_line() +
facet_wrap(~ gene, scales = "free_y") +
theme_bw() +
theme(panel.grid = element_blank()) +
scale_color_manual(name = "Gender", labels = c("F", "M"),
values = c("royalblue", "deeppink"))
ERROR
Error in ggplot(data = mean_exp_by_time_sex, mapping = aes(x = time, y = mean_exp, : could not find function "ggplot"
Composer des graphques
Le faceting est un super outil pour diviser un graphique en plusieurs sous-graphiques, mais parfois on aimerait plutôt obtenir une figure unique qui contient plusieurs graphiques indépendants, i.e. des graphiques basés sur différentes variables ou même différents data frames.
Commençons par créer les deux graphiques que nous souhaitons disposer l’un à côté de l’autre.
Le premier graphique compte le nombre de gènes uniques par
chromosome. Nous devons d’abord réorganiser les niveaux de
chromosome_name
et filtrer les gènes uniques par
chromosome. Nous modifions également l’échelle de l’axe y en une échelle
log10 pour une meilleure lisibilité.
R
arn$chromosome_name <- factor(rna$chromosome_name,
niveaux = c(1:19,"X","Y"))
ERROR
Error in factor(rna$chromosome_name, niveaux = c(1:19, "X", "Y")): unused argument (niveaux = c(1:19, "X", "Y"))
R
count_gene_chromosome <- rna %> % select(chromosome_name, gene) %>%
distinct() %>% ggplot() +
geom_bar(aes(x = chromosome_name), fill = "seagreen",
position = "esquive", stat = "count") +
labs(y = "log10(n gènes)", x = "chromosome") +
scale_y_log10()
ERROR
Error in rna %> % select(chromosome_name, gene) %>% distinct() %>% ggplot(): could not find function "%>%"
R
count_gene_chromosome
ERROR
Error: object 'count_gene_chromosome' not found
Ci-dessous, nous supprimons également complètement la légende en
mettant legend.position
à"none"
.
R
exp_boxplot_sex <- ggplot(rna, aes(y=expression_log, x = as.factor(time),
color=sex)) +
geom_boxplot(alpha = 0) +
labs(y = "Exp moyenne du gène",
x = "time") + theme(legend.position = "none")
ERROR
Error in ggplot(rna, aes(y = expression_log, x = as.factor(time), color = sex)): could not find function "ggplot"
R
exp_boxplot_sex
ERROR
Error: object 'exp_boxplot_sex' not found
Le package patchwork
fournit une approche élégante pour combiner des figures en utilisant le
« + » pour disposer les figures (typiquement côte à côte). Plus
précisément, le |
les dispose explicitement côte à côte et
/
les empile les uns sur les autres .
R
install.packages("patchwork")
R
library("patchwork")
ERROR
Error in library("patchwork"): there is no package called 'patchwork'
R
count_gene_chromosome + exp_boxplot_sex
ERROR
Error: object 'count_gene_chromosome' not found
R
## ou count_gene_chromosome | exp_boxplot_sex
R
count_gene_chromosome / exp_boxplot_sex
ERROR
Error: object 'count_gene_chromosome' not found
Nous pouvons encore améliorer l’aspect de la composition finale avec
plot_layout
pour créer des mises en page plus
complexes :
R
count_gene_chromosome + exp_boxplot_sex + plot_layout(ncol = 1)
ERROR
Error: object 'count_gene_chromosome' not found
R
count_gene_chromosome +
(count_gene_chromosome + exp_boxplot_sex) +
exp_boxplot_sex +
plot_layout(ncol = 1)
ERROR
Error: object 'count_gene_chromosome' not found
Le dernier graphique peut également être créé à l’aide des opérateurs
de composition |
et /
:
R
count_gene_chromosome /
(count_gene_chromosome | exp_boxplot_sex) /
exp_boxplot_sex
ERROR
Error: object 'count_gene_chromosome' not found
Apprenez-en plus sur patchwork
sur sa page Web ou dans cette
vidéo.
Une autre possibilité est le package
gridExtra
qui permet de combiner des
ggplots séparés en une seule figure en utilisant
grid.arrange()
:
R
install.packages("gridExtra")
R
library("gridExtra")
ERROR
Error in library("gridExtra"): there is no package called 'gridExtra'
R
grid.arrange(count_gene_chromosome, exp_boxplot_sex, ncol = 2)
ERROR
Error in grid.arrange(count_gene_chromosome, exp_boxplot_sex, ncol = 2): could not find function "grid.arrange"
En plus des arguments ncol
et nrow
,
utilisés pour créer des arrangements simples, il existe des outils pour
construire
des dispositions plus complexes.
Exporter des graphiques
Après avoir créé votre graphique, vous pouvez le sauvegarder dans un fichier, avec votre format préféré. L’onglet Export dans le volet Plot de RStudio enregistrera vos graphiques, mais néanmoins à basse résolution, ce qui pourrait compromettre leur publication dans de nombreuses revues et qui ne s’adaptera pas bien aux posters de grande taille.
Utilisez plutôt la fonction ggsave()
, qui vous permet de
modifier facilement la dimension et la résolution de votre tracé en
modifiant les arguments appropriés (width
,
height
et dpi
).
Assurez-vous d’avoir le dossier fig_output/
dans votre
répertoire de travail.
R
my_plot <- ggplot(data = mean_exp_by_time_sex,
mapping = aes(x = time, y = mean_exp, color = sex)) +
geom_line() +
facet_wrap(~ gene, scales = "free_y") +
labs(title = "Mean gene expression by duration of the infection",
x = "Duration of the infection (in days)",
y = "Mean gene expression") +
guides(color=guide_legend(title="Gender")) +
theme_bw() +
theme(axis.text.x = element_text(colour = "royalblue4", size = 12),
axis.text.y = element_text(colour = "royalblue4", size = 12),
text = element_text(size = 16),
panel.grid = element_line(colour="lightsteelblue1"),
legend.position = "top")
ggsave("fig_output/mean_exp_by_time_sex.png", my_plot, width = 15,
height = 10)
# This also works for grid.arrange() plots
combo_plot <- grid.arrange(count_gene_chromosome, exp_boxplot_sex,
ncol = 2, widths = c(4, 6))
ggsave("fig_output/combo_plot_chromosome_sex.png", combo_plot,
width = 10, dpi = 300)
Remarque : Les paramètres “width” et “height” déterminent également la taille de la police dans le graphique enregistré.
Autres packages pour la visualisation
ggplot2
est un package très puissant qui s’intègre très
bien dans l’ensemble tidy data et tidy tools. Il
existe cependant d’autres packages de visualisation dans R qu’il est
intéressant de connaître également.
Base graphics
Le système graphique par défaut fourni avec R, souvent appelé
base R graphics est simple et rapide. Il est basé sur le
painter’s or canvas model, où différentes sorties sont
directement superposées les unes sur les autres (voir figure @ref(fig:paintermodel)). C’est une différence
fondamentale avec ggplot2
(et avec lattice
,
décrit ci-dessous), qui renvoie des objets dédiés, qui sont visualisés à
l’écran ou dans un fichier, et qui peuvent même être modifiés.
R
par(mfrow = c(1, 3))
plot(1:20, main = "Première couche, produite avec plot(1:20)")
plot(1:20, main = "Une ligne rouge horizontale, ajoutée avec abline(h = 10)")
abline(h = 10, col = "red")
plot(1:20, main = "Un rectangle , ajouté avec rect(5, 5, 15, 15)")
abline(h = 10, col = "red")
rect(5, 5, 15, 15, lwd = 3 )

Une autre différence importante est que les fonctions de base
graphics essaient de deviner ce que l’utilisateur veut faire, en
fonction de leur type d’entrée, c’est-à-dire qu’elles adapteront leur
comportement en fonction de la classe de leur entrée. C’est encore une
fois très différent de ce que nous avons avec ggplot2
, qui
n’accepte que les data frames en entrée, et qui nécessite que
les graphiques soient construits petit à petit.
R
par(mfrow = c(2, 2))
boxplot(rnorm(100),
main = "Boxplot de rnorm(100)")
boxplot(matrix(rnorm( 100), ncol = 10),
main = "Boxplot de la matrice(rnorm(100), ncol = 10)")
hist(rnorm(100))
hist( matrice(rnorm(100), ncol = 10))
ERROR
Error in matrice(rnorm(100), ncol = 10): could not find function "matrice"

L’approche ‘clé sur porte’ de base graphics peut être très
efficace pour des figures simples et standards, qui peuvent être
produites très rapidement avec une seule ligne de code et une seule
fonction telle que plot
, hist
, ou
boxplot
, … Les valeurs par défaut ne sont cependant pas
toujours les plus pertinentes et le peaufinage des figures peut devenir
long et fastidieux, surtout lorsqu’elles deviennent plus complexes (par
exemple pour le faceting).
Le package lattice
Le package lattice
est similaire à
ggplot2
dans le sens où il utilise des data frames
en entrée, renvoie des objets graphiques et prend en charge le
faceting. Cependant, lattice
n’est pas basé sur la
Grammar of Graphics et a une interface plus alambiquée.
Une bonne référence pour le package lattice
est @latticebook.
Key Points
- Visualisation en R