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’argument data

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é dans aes().
  • 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 R hexbin 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 variable time, grâce à l’argument fill.

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 )
Successive layers added on top of each other.
Successive layers added on top of each other.

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"
Plotting boxplots (top) and histograms (bottom) vectors (left) or a matrices (right).
Plotting boxplots (top) and histograms (bottom) vectors (left) or a matrices (right).

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