Annoter ggplot2

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Clara de moncuit
Messages : 3
Enregistré le : 28 Aoû 2020, 07:25

Annoter ggplot2

Messagepar Clara de moncuit » 01 Sep 2020, 09:00

Bonjour,

Je suis débutante sur R, j'ai réalisé un ggplot avec plusieurs données, afin de voir à la fois une évolution entre les années, et entre mes habitats, voici ma ligne de code et le graphique obtenu :

ggplot(habitatIF)+geom_boxplot(aes(x="2015",y=IF_note_2015,color=habitat))+geom_boxplot(aes(x="2020",y=IF_note_2020,color=habitat))+facet_grid(~habitat)+labs(x="Année",y="IF")

habitat IF_note_2015 IF_note_2020
6210 19 39 54
6210 19 24 37
4030 13 0

Image


J'ai réalisé un pairwise.wilcox.test en amont afin de déterminer les différences significatives. Je souhaite maintenant annoter chaque boxplot avec des lettres pour montrer la significativité entre les différents éléments, cependant je n'arrive pas à annoter un seul boxplot à la fois, avec la fonction annotate, lorsque je met annoter x1, il annote tout les boxplot en 2015. Voici ce que je souhaite obtenir (ajouter sur paint) :

Image


Comment puis je procéder ?
Merci de vos réponses

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Annoter ggplot2

Messagepar Mickael Canouil » 01 Sep 2020, 10:52

Bonjour,

ggplot2 exploite un format dit "long" pour éviter d'avoir à gérer les différentes modalités, comme ici les différentes dates.
Vous pouvez effectuer la transformation comme suit:

Code : Tout sélectionner

habitatIF <- read.table(header = TRUE, text = "habitat IF_note_2015 IF_note_2020
6210 19 39
6210 19 24
4030 13 0"
)

library(tidyr)
habitatIF_long <- pivot_longer(
  data = habitatIF, 
  cols 
= starts_with("IF_note"),
  names_pattern = ".*_([0-9]+)",
  names_to = "year",
  values_to = "IF_note"

Code : Tout sélectionner

habitatIF_long
#> # A tibble: 6 x 3
#>   habitat year  IF_note
#>     <int> <chr>   <int>
#> 1    6210 2015       19
#> 2    6210 2020       39
#> 3    6210 2015       19
#> 4    6210 2020       24
#> 5    4030 2015       13
#> 6    4030 2020        0
 

Ce qui vous donne le code ggplot2 suivant

Code : Tout sélectionner

ggplot(habitatIF) +
  aes(= year, y = IF_note, color = habitat)
  geom_boxplot() +
  facet_grid(~habitat) +
  labs(= "Année", y = "IF")

Concernant les annotations, voici un exemple reproductible.

Code : Tout sélectionner

library(palmerpenguins)
library(ggplot2)
p_base <- ggplot(na.exclude(penguins)) +
  aes(= sex, y = body_mass_g) +
  geom_boxplot() +
  facet_grid(cols = vars(species, island))

p_base

Image
Notez le format de la table d'annotation, elle contient les facets et les coordonnées (1.5, correspond à la valeur centrale entre deux facteurs)

Code : Tout sélectionner

library(data.table)
penguins_ttest <- as.data.table(na.exclude(penguins))[, 
  list
(
    pvalue = t.test(formula = body_mass_g ~ sex, data = .SD)$p.value,
    x = 1.5,
    y = max(body_mass_g) + diff(range(body_mass_g)) * 0.1
  
), 
  by 
= c("species", "island")
]

Code : Tout sélectionner

penguins_ttest[]
#>      species    island       pvalue   x      y
#> 1:    Adelie Torgersen 3.993168e-08 1.5 4880.0
#> 2:    Adelie    Biscoe 8.750160e-08 1.5 4967.5
#> 3:    Adelie     Dream 2.710669e-12 1.5 4825.0
#> 4:    Gentoo    Biscoe 1.867760e-28 1.5 6535.0
#> 5: Chinstrap     Dream 2.264432e-06 1.5 5010.0    

Code : Tout sélectionner

p_base +
  geom_text(
    data = penguins_ttest,
    mapping = aes(
      x = x, 
      y 
= y, 
      label 
= prettyNum(pvalue, scientific = TRUE, digits = 3, nsmall = 3)
    )
  )


Image

Vous pouvez aussi regarder l'extension ggpubr (https://rpkgs.datanovia.com/ggpubr/index.html)
Image

A noter que personnellement, la visualisation que vous souhaitez réaliser ne me semble pas être une bonne idée de par la complexité de la lecture.

Cordialement,
Mickaël
mickael.canouil.fr | rlille.fr

Facundo Muñoz
Messages : 156
Enregistré le : 04 Juil 2019, 09:58
Contact :

Re: Annoter ggplot2

Messagepar Facundo Muñoz » 01 Sep 2020, 11:15

Bonjour,

juste ajouter que si vous utilisez les facettes pour idéntifier les habitats, inutile de le faire en plus par les couleurs. Cela n'ajoute de l'information et par contre ça prenne de l'espace dans la figure et demande un effort cognitif pour l'interpréter.

Cordialement,
ƒacu.-

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Annoter ggplot2

Messagepar Mickael Canouil » 01 Sep 2020, 11:20

Facundo Muñoz a écrit :Bonjour,

juste ajouter que si vous utilisez les facettes pour idéntifier les habitats, inutile de le faire en plus par les couleurs. Cela n'ajoute de l'information et par contre ça prenne de l'espace dans la figure et demande un effort cognitif pour l'interpréter.

Cordialement,


Si la question est simplement la place occupée par la légende, Il suffit d'ajouter au choix :

Code : Tout sélectionner

... +
geom_boxplot(..., show.legend = FALSE) +
... 

Code : Tout sélectionner

... +
theme(legend.position = "none"

Code : Tout sélectionner

... +
guides(colour = "none"


La question est plus sur les comparaisons inter et intra facet ... de ce fait je pense que le "problème" est plus l'usage de facet_grid() que celui de l'aesthetique "colour" (et la légende associée).

EDIT: un livre sur les principes de visualisations https://clauswilke.com/dataviz/index.html par Claus O. Wilke, auteur de plusieurs extensions autour de ggplot2
Mickaël
mickael.canouil.fr | rlille.fr

Clara de moncuit
Messages : 3
Enregistré le : 28 Aoû 2020, 07:25

Re: Annoter ggplot2

Messagepar Clara de moncuit » 01 Sep 2020, 12:07

Merci de vos réponses, je vais tester cela. Effectivement je peux enlever la légende sur le côté qui n'est pas nécessaire, et pour le graphique en lui même je cherche à mettre en évidence l'évolution entre 2015 et 2020 selon les habitats et les boxplot me semblaient le plus approprié, mais au niveau de la significativité cela complexifie un peu le graphique effectivement, mais je ne vois pas comment d'autre, je peux visuellement résumer autant d'informations.

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Annoter ggplot2

Messagepar Mickael Canouil » 01 Sep 2020, 12:35

Le "problème" soulevé n'était pas sur le boxplot, mais le facet_grid.
Pourquoi découper un graphique et donc rendre les morceaux indépendants quand les comparisons sont transversales ?

Code : Tout sélectionner

library(palmerpenguins)
library(ggplot2)
library(ggpubr)

comparisons <- combn(
  x = sort(unique(with(na.exclude(penguins), paste(species, island, sep = "\n")))),
  m = 2, 
  simplify 
= FALSE
)

ggplot(na.exclude(penguins)) +
  aes(
    x = paste(species, island, sep = "\n"), 
    y 
= body_mass_g, 
    colour 
= paste(species, island)
  ) +
  geom_boxplot(show.legend = FALSE) +
  stat_compare_means(comparisons = comparisons, method = "t.test"


Image
Mickaël
mickael.canouil.fr | rlille.fr

Clara de moncuit
Messages : 3
Enregistré le : 28 Aoû 2020, 07:25

Re: Annoter ggplot2

Messagepar Clara de moncuit » 01 Sep 2020, 13:08

Ah oui je vois c'est une idée, j'ai testé mais cela me fait énormément de comparaison, et le graphique en devient très peu lisible, comment est il possible de garder sur le graphique uniquement ceux qui ont une p-value inférieure à 0.05 ? Afin de garder uniquement les tests significatifs

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Annoter ggplot2

Messagepar Mickael Canouil » 02 Sep 2020, 08:25

Il faudra passer en mode "manuel" (exemple ci-dessous).
Pour toute autre personnalisation, je vous suggère de lire la documentation des fonctions utilisé ci-dessous et notamment les sites internets de ces extensions qui disposent de nombreux exemples illustrés.

Code : Tout sélectionner

library(palmerpenguins)
library(ggplot2)
library(ggpubr)

dta <- na.exclude(penguins)
dta[["x"]] <- paste(dta[["species"]], dta[["island"]], sep = "\n")

Code : Tout sélectionner

comparisons <- combn(
  x = sort(unique(with(na.exclude(penguins), paste(species, island, sep = "\n")))),
  m = 2, 
  simplify 
= FALSE
)

ggplot(data = dta) +
  aes(= x, y = body_mass_g, colour = x) +
  geom_boxplot(show.legend = FALSE) +
  stat_compare_means(comparisons = comparisons, method = "t.test"

Image

Code : Tout sélectionner

dta_annot <- compare_means(
  formula = body_mass_g ~ x, 
  data 
= dta, 
  method 
= "t.test"
)
dta_annot <- dta_annot[dta_annot$p <= 0.05, ]
dta_annot[["y.position"]] <- max(dta[["body_mass_g"]]) + 
  diff
(range(dta[["body_mass_g"]])) * seq(0.05, 0.20, length.out = nrow(dta_annot))

Code : Tout sélectionner

ggplot(data = dta) +
  aes(= x, y = body_mass_g, colour = x) +
  geom_boxplot(show.legend = FALSE) +
  stat_pvalue_manual(dta_annot, label = "p = {format(p, digits = 3, scientific = TRUE)}")

Image

Cordialement,
Mickaël
mickael.canouil.fr | rlille.fr


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité