Étiquettes des axes de rotation et d'espacement dans ggplot2

671

J'ai un tracé 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 qu'elles soient 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))

entrez la description de l'image ici

Christopher DuBois
la source

Réponses:

1114

Remplacez la dernière ligne par

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 lors d'une rotation. Lorsque vous tournez de +/- 90 degrés, vous souhaitez généralement qu'il soit aligné sur le bord à la place:

texte alternatif

L'image ci-dessus provient de ce billet de blog .

Jonathan Chang
la source
95
Dans la dernière version de ggplot2, la commande serait: q + theme(axis.text.x=element_text(angle = -90, hjust = 0))
rnorberg
55
Pour ceux pour qui il ne se comporte pas comme décrit ici, essayez theme(axis.text.x=element_text(angle = 90, vjust = 0.5)). Depuis ggplot2 0.9.3.1, cela semble être la solution.
lilster
42
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))
jupp0r
32
@ jupp0r est correct. theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))EST CELUI QUI FONCTIONNE ACTUELLEMENT.
51
si vous vouliez des étiquettes tournées à 45 ° (plus faciles à lire) theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))donne de bons résultats
jan-glx
89

Pour rendre le texte sur les étiquettes de graduation entièrement visible et lu dans la même direction que l'étiquette de l'axe y, changez la dernière ligne en

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

Utilisation coord_flip()

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

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

entrez la description de l'image ici


Dans Ch 3.9 de R pour Data Science , Wickham et Grolemund répondent à cette question exacte:

coord_flip()commute les axes x et y. Ceci est utile (par exemple), si vous voulez des boîtes à moustaches horizontales. Il est également utile pour les étiquettes longues: il est difficile de les faire tenir sans se chevaucher sur l'axe des x.

Rich Pauloo
la source
26

Je voudrais fournir une solution alternative, une solution robuste similaire à ce que je suis sur le point de proposer était requise dans la dernière version de ggtern , depuis l'introduction de la fonction de rotation du canevas.

Fondamentalement, vous devez déterminer les positions relatives à l'aide de la trigonométrie, en créant une fonction qui renvoie un element_textobjet, un angle (c.-à-d. Degrés) et un positionnement (c.-à-d. L'un des x, y, en haut ou à droite) donnés.

#Load Required Libraries
library(ggplot2)
library(gridExtra)

#Build Function to Return Element Text Object
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' must be one of [%s]",paste(names(positions),collapse=", ")),call.=FALSE)
  if(!is.numeric(angle))
    stop("'angle' must be numeric",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)
}

Franchement, à mon avis, je pense qu'une option "auto" devrait être mise à disposition dans ggplot2les arguments hjustet vjust, quand on spécifie l'angle, de toute façon, permet de montrer comment cela fonctionne.

#Demonstrate Usage for a Variety of 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

Nicholas Hamilton
la source
1
Je n'obtiens pas les mêmes résultats, pour moi le texte de l'axe n'est jamais bien ajusté en utilisant votre méthode auto. Cependant, l'utilisation a rads = (-angle - positions[[ position ]])*pi/180produit de meilleurs placements. Notez le signe moins supplémentaire avant l'angle. Merci pour le code quand même :)
asac
7

Le paquet ggpubr propose un raccourci qui fait la bonne chose par défaut (aligner le texte à droite, aligner la zone de texte au milieu à cocher):

library(ggplot2)
diamonds$cut <- paste("Super Dee-Duper", as.character(diamonds$cut))
q <- qplot(cut, carat, data = diamonds, geom = "boxplot")
q + ggpubr::rotate_x_text()

Créé le 2018-11-06 par le package reprex (v0.2.1)

Trouvé avec une recherche GitHub pour les noms d'arguments pertinents: https://github.com/search?l=R&q=element_text+angle+90+vjust+org%3Acran&type=Code

krlmlr
la source
6

Alternativement, ggplot 3.3.0fournit guide_axis(n.dodge = 2)(comme guideargument à scale_..ou comme xargument à guides) pour surmonter le problème de sur-tracé 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

jan-glx
la source
1

Pour obtenir des libellés x tick lisibles sans dépendances supplémentaires, vous souhaitez utiliser:

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

Cela fait pivoter les étiquettes de graduation de 90 ° dans le sens antihoraire et les aligne verticalement à leur extrémité ( hjust = 1) et leurs centres horizontalement avec la graduation correspondante ( vjust = 0.5).

Exemple complet:

library(ggplot2)
data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))
q <- qplot(cut,carat,data=diamonds,geom="boxplot")
q + theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))


Notez que les paramètres de justification verticale / horizontale vjust/ hjustde element_textsont relatifs au texte. Par conséquent, vjustest responsable de l' alignement horizontal .

Sans vjust = 0.5cela, cela ressemblerait à ceci:

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

Sans hjust = 1cela, cela ressemblerait à ceci:

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

Si pour certains (filaire) raison pour laquelle vous vouliez tourner la tique étiquettes 90 ° dans le sens horaire ( de telle sorte qu'ils peuvent être lus à partir de la gauche) , vous devez utiliser: q + theme(axis.text.x = element_text(angle = -90, vjust = 0.5, hjust = -1)).

Tout cela a déjà été discuté dans les commentaires de cette réponse mais je reviens à cette question si souvent, que je veux une réponse dont je peux simplement copier sans lire les commentaires.

jan-glx
la source
0

Une alternative à coord_flip()est d'utiliser le ggstancepackage. L'avantage est qu'il facilite la combinaison des graphiques avec d'autres types de graphiques et vous pouvez, peut-être plus important encore, définir des rapports d'échelle fixes pour votre système de coordonnées .

library(ggplot2)
library(ggstance)

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

ggplot(data=diamonds, aes(carat, cut)) + geom_boxploth()

Créé le 2020-03-11 par le package reprex (v0.3.0)

Tjebo
la source