web-dev-qa-db-fra.com

Annoter du texte sur une facette individuelle dans ggplot2

Je veux annoter du texte sur la dernière facette de l'intrigue avec le code suivant:

library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + facet_grid(. ~ cyl)
p <- p + annotate("text", label = "Test", size = 4, x = 15, y = 5)
print(p)

enter image description here

Mais ce code annote le texte sur chaque facette. J'apprécierais beaucoup si vous me guidiez comment obtenir le texte annoté sur une seule face Merci d'avance.

103
MYaseen208

Typiquement, vous feriez quelque chose comme ça:

ann_text <- data.frame(mpg = 15,wt = 5,lab = "Text",
                       cyl = factor(8,levels = c("4","6","8")))
p + geom_text(data = ann_text,label = "Text")

Cela devrait fonctionner sans spécifier complètement la variable facteur, mais émettra probablement quelques avertissements:

enter image description here

113
joran

Voici l'intrigue sans annotations de texte:

library(ggplot2)

p <- ggplot(mtcars, aes(mpg, wt)) +
  geom_point() +
  facet_grid(. ~ cyl) +
  theme(panel.spacing = unit(1, "lines"))
p

 plot without text annotations

Créons un cadre de données supplémentaire pour contenir les annotations de texte:

dat_text <- data.frame(
  label = c("4 cylinders", "6 cylinders", "8 cylinders"),
  cyl   = c(4, 6, 8)
)
p + geom_text(
  data    = dat_text,
  mapping = aes(x = -Inf, y = -Inf, label = label),
  hjust   = -0.1,
  vjust   = -1
)

 plot with text annotations at edges

Alternativement, nous pouvons spécifier manuellement la position de chaque étiquette:

dat_text <- data.frame(
  label = c("4 cylinders", "6 cylinders", "8 cylinders"),
  cyl   = c(4, 6, 8),
  x     = c(20, 27.5, 25),
  y     = c(4, 4, 4.5)
)

p + geom_text(
  data    = dat_text,
  mapping = aes(x = x, y = y, label = label)
)

 plot with manually positioned text labels

Nous pouvons également étiqueter les parcelles sur deux facettes:

dat_text <- data.frame(
  cyl   = c(4, 6, 8, 4, 6, 8),
  am    = c(0, 0, 0, 1, 1, 1)
)
dat_text$label <- sprintf(
  "%s, %s cylinders",
  ifelse(dat_text$am == 0, "automatic", "manual"),
  dat_text$cyl
)
p +
  facet_grid(am ~ cyl) +
  geom_text(
    size    = 5,
    data    = dat_text,
    mapping = aes(x = Inf, y = Inf, label = label),
    hjust   = 1.05,
    vjust   = 1.5
  )

 facet by two variables

Remarques:

  • Vous pouvez utiliser -Inf et Inf pour positionner du texte sur les bords d'un panneau.
  • Vous pouvez utiliser hjust et vjust pour ajuster la justification du texte.
  • Le bloc de données d'étiquette de texte dat_text doit avoir une colonne qui fonctionne avec votre facet_grid() ou votre facet_wrap().
64
Kamil Slowikowski

Je pense que pour la réponse ci-dessus, lab = "Texte" est inutile, le code ci-dessous est également correct.

ann_text <- data.frame(mpg = 15,wt = 5,
                       cyl = factor(8,levels = c("4","6","8")))
p + geom_text(data = ann_text,label = "Text" )

Cependant, si vous voulez étiqueter différemment dans différents sous-graphiques, tout se passera bien ainsi:

ann_text <- data.frame(mpg = c(14,15),wt = c(4,5),lab=c("text1","text2"),
                       cyl = factor(c(6,8),levels = c("4","6","8")))
p + geom_text(data = ann_text,aes(label =lab) )
21
kdyhl

Si vous recherchez un moyen facile d’étiqueter des facettes pour des rapports ou des publications, la version de développement de Egg package contient la fonction tag_facet()

library(ggplot2)

p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + 
  facet_grid(. ~ cyl) +
  theme_bw(base_size = 12)

# devtools::install_github("baptiste/Egg")
library(Egg)

tag_facet(p)

tag_facet(p, x = Inf, y = Inf, hjust = 1)

tag_facet(p, x = -Inf, y = -Inf, vjust = -1)

10
Tung

Je ne connaissais pas le package Egg, voici donc une solution simple pour le package ggplot2

library(tidyverse)
library(magrittr)
Data1=data.frame(A=runif(20, min = 0, max = 100), B=runif(20, min = 0, max = 250), C=runif(20, min = 0, max = 300))
Data2=data.frame(A=runif(20, min = -10, max = 50), B=runif(20, min = -5, max = 150), C=runif(20, min = 5, max = 200))
bind_cols(
Data1 %>% gather("Vars","Data_1"),
Data2 %>% gather("Vars","Data_2")
) %>% select(-Vars1) -> Data_combined
Data_combined %>%
  group_by(Vars) %>%
  summarise(r=cor(Data_1,Data_2),
            r2=r^2,
            p=(pt(abs(r),nrow(.)-2)-pt(-abs(r),nrow(.)-2))) %>%
  mutate(rlabel=paste("r:",format(r,digits=3)),
         plabel=paste("p:",format(p,digits=3))) ->
  label_df 
label_df %<>% mutate(x=60,y=190)
Data_combined %>%
  ggplot(aes(x=Data_1,y=Data_2,color=Vars)) +
  geom_point() + 
  geom_smooth(method="lm",se=FALSE) +
  geom_text(data=label_df,aes(x=x,y=y,label=rlabel),inherit.aes = FALSE) + 
  geom_text(data=label_df,aes(x=x,y=y-10,label=plabel),inherit.aes = FALSE) + 
    facet_wrap(~ Vars)
0
Erich Neuwirth

Développant légèrement l'excellente réponse de joran, afin de clarifier le fonctionnement de la base de données d'étiquettes. 

Vous pouvez considérer "mpg" et "wt" comme les coordonnées x et y, respectivement (je trouve qu'il est plus facile de garder trace des noms de variables d'origine que de les renommer, comme dans la réponse excellente de Kamil). Vous avez besoin d’une ligne par étiquette et la colonne "cyl" indique la facette à laquelle chaque ligne est associée. 

ann_text<-data.frame(mpg=c(25,15),wt=c(3,5),cyl=c(6,8),label=c("Label 1","Label 2"))

ann_text
>  mpg wt cyl  label
>  25  3   6   Label 1
>  15  5   8   Label 2

p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + facet_grid(. ~ factor(cyl))
p + geom_text(data = ann_text,label=ann_text$label)

 plot with labels

0
John