826 votes

Faire pivoter et espacer les étiquettes des axes dans ggplot2

J'ai un graphique où l'axe des x est un facteur dont les étiquettes sont longues. Bien que ce ne soit probablement pas une visualisation idéale, pour l'instant, je voudrais simplement faire pivoter ces étiquettes pour les rendre verticales. J'ai compris cette partie avec le code ci-dessous, mais comme vous pouvez le voir, les étiquettes ne sont pas totalement visibles.

data(diamonds)
diamonds$cut <- paste("Super Dee-Duper", as.character(diamonds$cut))
q <- qplot(cut, carat, data=diamonds, geom="boxplot")
q + opts(axis.text.x=theme_text(angle=-90))

enter image description here

6 votes

Comme ggplot 3.3.0 est maintenant sorti, à mon avis, la réponse acceptée devrait être changée en celle de jan-glx.

1366voto

Jonathan Chang Points 6231

Change the last line to

q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))

Par défaut, les axes sont alignés au centre du texte, même lorsqu'ils sont tournés. Lorsque vous tournez de +/- 90 degrés, vous voulez généralement qu'ils soient alignés sur le bord :

texte alternatif

L'image ci-dessus provient de cet article de blog.

115 votes

Dans la dernière version de ggplot2, la commande serait : q + theme(axis.text.x=element_text(angle = -90, hjust = 0))

60 votes

À ceux pour qui hjust ne se comporte pas comme décrit ici, essayez theme(axis.text.x=element_text(angle = 90, vjust = 0.5)). À partir de ggplot2 0.9.3.1, cela semble être la solution.

44 votes

En fait, j'ai dû combiner les deux solutions ci-dessus pour obtenir des étiquettes correctement alignées: q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))

167voto

YAK Points 185

ggplot 3.3.0 corrige cela en fournissant guide_axis(angle = 90) (comme argument guide pour scale_.. ou comme argument x pour guides) :

library(ggplot2)
data(diamonds)
diamonds$cut <- paste("Super Dee-Duper", as.character(diamonds$cut))

ggplot(diamonds, aes(cut, carat)) +
  geom_boxplot() +
  scale_x_discrete(guide = guide_axis(angle = 90)) +
  # ... ou, de manière équivalente:
  # guides(x =  guide_axis(angle = 90)) +
  NULL

De la documentation de l'argument angle:

Par rapport au réglage de l'angle dans theme() / element_text(), cela utilise également des heuristiques pour choisir automatiquement le hjust et le vjust que vous voulez probablement.


Alternativement, il fournit également guide_axis(n.dodge = 2) (comme argument guide pour scale_.. ou comme argument x pour guides) pour surmonter le problème de superposition en esquivant les étiquettes verticalement. Cela fonctionne assez bien dans ce cas :

library(ggplot2)
data(diamonds)
diamonds$cut <- paste("Super Dee-Duper", as.character(diamonds$cut))

ggplot(diamonds, aes(cut, carat)) + 
  geom_boxplot() +
  scale_x_discrete(guide = guide_axis(n.dodge = 2)) +
  NULL

143voto

Rich Pauloo Points 2577

Utilisez coord_flip()

data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))

qplot(cut, carat, data = diamonds, geom = "boxplot") +
  coord_flip()

entrer la description de l'image ici


Ajouter str_wrap()

# envelopper le texte à 15 espaces maximum
library(stringr)
diamonds$cut2 <- str_wrap(diamonds$cut, width = 15)
qplot(cut2, carat, data = diamonds, geom = "boxplot") +
  coord_flip()

entrer la description de l'image ici


Dans le chapitre 3.9 de R for Data Science, Wickham and Grolemund abordent cette question précise:

coord_flip() inverse les axes x et y. C'est utile (par exemple), si vous souhaitez des boxplots horizontaux. C'est également utile pour les longs libellés: il est difficile de les faire tenir sans se chevaucher sur l'axe des x.

100voto

e3bo Points 474

Pour rendre le texte sur les étiquettes des graduations complètement visible et le lire dans la même direction que le libellé de l'axe des y, changez la dernière ligne en

q + theme(axis.text.x=element_text(angle=90, hjust=1))

33voto

Nicholas Hamilton Points 630

Je voudrais proposer une solution alternative, une solution robuste similaire à ce que je m'apprête à proposer était nécessaire dans la dernière version de ggtern, depuis l'introduction de la fonction de rotation du canvas.

Fondamentalement, vous devez déterminer les positions relatives en utilisant la trigonométrie, en construisant une fonction qui renvoie un objet element_text, en donnant l'angle (c'est-à-dire en degrés) et les informations de positionnement (c'est-à-dire l'une des informations suivantes : x, y, haut ou droite).

#Charger les bibliothèques requises
library(ggplot2)
library(gridExtra)

#Construire une fonction pour retourner un objet Element Text
rotatedAxisElementText = function(angle, position='x'){
  angle     = angle[1]; 
  position  = position[1]
  positions = list(x=0,y=90,top=180,right=270)
  if(!position %in% names(positions))
    stop(sprintf("'position' doit être l'un des [%s]",paste(names(positions),collapse=", ")),call.=FALSE)
  if(!is.numeric(angle))
    stop("'angle' doit être numérique",call.=FALSE)
  rads  = (angle - positions[[ position ]])*pi/180
  hjust = 0.5*(1 - sin(rads))
  vjust = 0.5*(1 + cos(rads))
  element_text(angle=angle,vjust=vjust,hjust=hjust)
}

Honnêtement, à mon avis, je pense qu'une option 'auto' devrait être disponible dans ggplot2 pour les arguments hjust et vjust, lors de la spécification de l'angle, quoi qu'il en soit, démontrons comment cela fonctionne ci-dessus.

#Démontrer l'utilisation pour une variété de rotations
df    = data.frame(x=0.5,y=0.5)
plots = lapply(seq(0,90,length.out=4),function(a){
  ggplot(df,aes(x,y)) + 
    geom_point() + 
    theme(axis.text.x = rotatedAxisElementText(a,'x'),
          axis.text.y = rotatedAxisElementText(a,'y')) +
    labs(title = sprintf("Rotated %s",a))
})
grid.arrange(grobs=plots)

Ce qui produit ce qui suit :

Exemple

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