2 votes

Axe des abscisses inversé contenant des données catégorielles et de nombreuses annotations

Je travaille sur une fonction qui crée un fichier compliqué de ggplot graphique. Le graphique comporte des dizaines d'annotations textuelles et rectangulaires, ainsi que des données catégorielles sous forme de barres. J'aimerais créer une option permettant d'inverser l'axe des x dans certaines situations. J'ai donc besoin d'ajouter une logique pour inverser l'axe si cette option est activée. Mais je rencontre des difficultés parce que l'inversion des groupements de données n'inverse pas les annotations (bien sûr). Mais je veux tout inverser.

Comment faire sans faire bouillir l'océan ?

library(tidyverse)

mtcars %>%
  mutate( make =  word(rownames(mtcars))) %>%
  group_by(make) %>%
  summarize(wt = sum(wt)) %>%
  head ->
  mt

p <- ggplot(mt, aes(x = make, y = wt)) +
  geom_bar(stat = "identity") +
  annotate(
    "rect",
    xmin = 1.5,
    xmax = 4.5,
    ymin = 4,
    ymax = 7,
    alpha = .5
  )  + 
  annotate("label", x = 3, y = 6, label = "WTF, y'all?") 
p

Je constate que je ne peux même pas utiliser scale_x_reverse pour une raison ou une autre :

p + scale_x_reverse() 
#> Error in -x: invalid argument to unary operator

Veuillez noter que l'exemple reproductible que je donne ici est très simplifié. Dans la pratique, j'ai plusieurs dizaines d'éléments de types différents sur mon graphique.

2voto

David Gohel Points 2590

scale_x_reverse est pour l'échelle continue. Ici, vous devrez jouer avec les facteurs et avec scale_x_discrete :

library(tidyverse)

mtcars %>%
  mutate( make =  word(rownames(mtcars))) %>%
  group_by(make) %>%
  summarize(wt = sum(wt)) %>%
  head %>% 
  mutate( make = as.factor(make) ) -> # make `make` as a factor
  mt

p <- ggplot(mt, aes(x = make, y = wt)) +
  geom_bar(stat = "identity") +
  annotate(
    "rect",
    xmin = 1.5,
    xmax = 4.5,
    ymin = 4,
    ymax = 7,
    alpha = .5
  )  + 
  annotate("label", x = 3, y = 6, label = "WTF, y'all?") 
p

# reverse used order of factor levels
p + scale_x_discrete(limits = rev(levels(mt$make)))

enter image description here

1voto

zx8754 Points 13573

Nous pourrions intégrer les étiquettes d'annotation et les ombres aux données d'entrée. Les annotations s'inverseront alors en même temps que l'ordre de l'axe des x. Quelque chose comme :

library(tidyverse)

# dummy data
mtcars %>%
  mutate(make =  word(rownames(mtcars))) %>%
  group_by(make) %>%
  summarize(wt = sum(wt)) %>%
  head ->
  mt

# Option to reverse, choose one
# if it is a function, pass an argument
# foo <- function(data, myReverseOption = FALSE, ...
myReverseOption = TRUE
myReverseOption = FALSE

mt$make <- as.factor(mt$make)

if(myReverseOption){
  mt$make <- factor(mt$make, levels = rev(levels(mt$make))) }

# add annotaions
mt <- mt %>% 
  mutate(
    myLabel = if_else(make == "Camaro", "OK, y'all?", NA_character_),
    myShade = grepl("^C", make))

# plot
ggplot(mt, aes(x = make, y = wt)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = myLabel), nudge_y = 1) +
  geom_rect(aes(xmin = (as.numeric(make) - 0.5) * myShade,
                xmax = (as.numeric(make) + 0.5) * myShade,
                ymin = 4, ymax = 6),
            alpha = 0.5) +
  ggtitle(ifelse(myReverseOption, "reversed", "original"))

enter image description here

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X