Rotazione e spaziatura delle etichette degli assi in ggplot2


671

Ho una trama in cui l'asse x è un fattore le cui etichette sono lunghe. Anche se probabilmente non è una visualizzazione ideale, per ora mi piacerebbe semplicemente ruotare queste etichette per essere verticali. Ho capito questa parte con il codice qui sotto, ma come puoi vedere, le etichette non sono totalmente visibili.

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))

inserisci qui la descrizione dell'immagine

Risposte:


1114

Cambia l'ultima riga in

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

Per impostazione predefinita, gli assi sono allineati al centro del testo, anche quando ruotati. Quando si ruota di +/- 90 gradi, di solito si desidera che sia allineato al bordo:

testo alternativo

L'immagine sopra è da questo post sul blog .


95
Nella versione più recente di ggplot2 il comando sarebbe: q + theme(axis.text.x=element_text(angle = -90, hjust = 0))
rnorberg,

55
A coloro per i quali hjust non si comporta come descritto qui, prova theme(axis.text.x=element_text(angle = 90, vjust = 0.5)). A partire da ggplot2 0.9.3.1 questa sembra essere la soluzione.
lilster,

42
In realtà, ho dovuto combinare le due soluzioni sopra per ottenere etichette correttamente allineate:q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
jupp0r

32
@ jupp0r è corretto. theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))L'UNICO FUNZIONA ATTUALMENTE.

51
se volevi etichette ruotate di 45 ° (più facili da leggere) theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))dà buoni risultati
jan-glx,

89

Per rendere il testo sulle etichette dei segni di spunta completamente visibili e leggere nella stessa direzione dell'etichetta dell'asse y, modificare l'ultima riga in

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

82

Uso coord_flip()

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

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

inserisci qui la descrizione dell'immagine


Nel Ch 3.9 di R for Data Science , Wickham e Grolemund parlano a questa domanda esatta:

coord_flip()cambia gli assi xey. Ciò è utile (ad esempio), se si desidera un diagramma a scatole orizzontale. È utile anche per etichette lunghe: è difficile farle adattarsi senza sovrapposizioni sull'asse x.


26

Vorrei fornire una soluzione alternativa, una soluzione robusta simile a quella che sto per proporre era richiesta nell'ultima versione di ggtern , da quando è stata introdotta la funzione di rotazione della tela.

Fondamentalmente, è necessario determinare le posizioni relative usando la trigonometria, costruendo una funzione che restituisca un element_textoggetto, dati l'angolo (cioè i gradi) e il posizionamento (cioè uno di x, y, in alto o a destra).

#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)
}

Francamente, secondo me, penso che un'opzione 'auto' dovrebbe essere resa disponibile ggplot2per gli argomenti hjuste vjust, quando si specifica l'angolo, comunque, si dimostra come funziona quanto sopra.

#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)

Che produce quanto segue:

Esempio


1
Non ottengo gli stessi risultati, per me il testo dell'asse non è mai ben regolato usando il tuo metodo automatico. Tuttavia, utilizzando rads = (-angle - positions[[ position ]])*pi/180posizionamenti migliori prodotti. Nota il segno meno aggiuntivo prima dell'angolo. Grazie comunque per il codice :)
asac,

7

Il pacchetto ggpubr offre un collegamento che fa la cosa giusta di default (allinea il testo a destra, allinea il centro per spuntare):

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()

Creato il 06-11-2018 dal pacchetto reprex (v0.2.1)

Trovato con una ricerca GitHub per i nomi degli argomenti pertinenti: https://github.com/search?l=R&q=element_text+angle+90+vjust+org%3Acran&type=Code


6

In alternativa, ggplot 3.3.0fornisce guide_axis(n.dodge = 2)(come guideargomento a scale_..o come xargomento a guides) per superare il problema di stampa eccessiva schivando le etichette verticalmente. Funziona abbastanza bene in questo caso:

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


1

Per ottenere etichette x tick leggibili senza dipendenze aggiuntive, si desidera utilizzare:

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

Ciò ruota le etichette di spunta di 90 ° in senso antiorario e le allinea verticalmente alla loro estremità ( hjust = 1) e i loro centri in senso orizzontale con il segno di spunta corrispondente ( vjust = 0.5).

Esempio completo:

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))


Si noti che i parametri di giustificazione verticale / orizzontale vjust/ hjustdi element_textsono relativi al testo. Pertanto, vjustè responsabile per l' orizzontale allineamento .

Senza di vjust = 0.5essa sarebbe simile a questo:

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

Senza di hjust = 1essa sarebbe simile a questo:

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

Se per qualche motivo (cablato) si voleva far ruotare il segno di spunta etichette di 90 ° in senso orario (in modo che possano essere lette da sinistra) si avrebbe bisogno di uso: q + theme(axis.text.x = element_text(angle = -90, vjust = 0.5, hjust = -1)).

Tutto questo è già stato discusso nei commenti di questa risposta, ma torno a questa domanda così spesso, che voglio una risposta da cui posso semplicemente copiare senza leggere i commenti.


0

Un'alternativa a coord_flip()è usare il ggstancepacchetto. Il vantaggio è che semplifica la combinazione dei grafici con altri tipi di grafico e puoi, forse ancora più importante, impostare rapporti di scala fissi per il tuo sistema di coordinate .

library(ggplot2)
library(ggstance)

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

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

Creato il 2020-03-11 dal pacchetto reprex (v0.3.0)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.