Cosa fanno hjust e vjust quando fanno una trama usando ggplot?


159

Ogni volta che faccio una trama usando ggplot, passo un po 'a cercare diversi valori per hjust e vjust in una riga come

+ opts(axis.text.x = theme_text(hjust = 0.5))

fare in modo che le etichette degli assi si allineino quando le etichette degli assi quasi toccano l'asse e sono a filo con esso (giustificate dall'asse, per così dire). Tuttavia, non capisco davvero cosa stia succedendo. Spesso, hjust = 0.5dà risultati così drammaticamente diversi hjust = 0.6, ad esempio, che non sono stato in grado di capirlo solo giocando con valori diversi.

Qualcuno può indicarmi una spiegazione esauriente di come funzionano le opzioni hjust e vjust?


1
Ho fatto un esempio specifico, nei commenti alla prima risposta. Apparentemente usare numeri al di fuori di 0-1 non è definito, il che, se non spiega perché hjust = -1 ha un comportamento bizzarro, almeno spiega che ci si aspetta bizzarro.
William Gunn,

Risposte:


277

I valori di hjuste vjustsono definiti solo tra 0 e 1:

  • 0 significa giustificato a sinistra
  • 1 significa giustificato a destra

Fonte: ggplot2, Hadley Wickham, pagina 196

(Sì, lo so che nella maggior parte dei casi puoi usarlo oltre questo intervallo, ma non mi aspetto che si comporti in alcun modo specifico. Questa è una specifica esterna.)

hjustcontrolla la giustificazione orizzontale e vjustcontrolla la giustificazione verticale.

Un esempio dovrebbe chiarire questo:

td <- expand.grid(
    hjust=c(0, 0.5, 1),
    vjust=c(0, 0.5, 1),
    angle=c(0, 45, 90),
    text="text"
)

ggplot(td, aes(x=hjust, y=vjust)) + 
    geom_point() +
    geom_text(aes(label=text, angle=angle, hjust=hjust, vjust=vjust)) + 
    facet_grid(~angle) +
    scale_x_continuous(breaks=c(0, 0.5, 1), expand=c(0, 0.2)) +
    scale_y_continuous(breaks=c(0, 0.5, 1), expand=c(0, 0.2))

inserisci qui la descrizione dell'immagine


Per capire cosa succede quando si modifica il hjusttesto nell'asse, è necessario comprendere che l'allineamento orizzontale per il testo dell'asse è definito non in relazione all'asse x, ma all'intero grafico (dove questo include il testo dell'asse y). (Questo è, a mio avviso, sfortunato. Sarebbe molto più utile avere l'allineamento rispetto all'asse.)

DF <- data.frame(x=LETTERS[1:3],y=1:3)
p <- ggplot(DF, aes(x,y)) + geom_point() + 
    ylab("Very long label for y") +
    theme(axis.title.y=element_text(angle=0))


p1 <- p + theme(axis.title.x=element_text(hjust=0)) + xlab("X-axis at hjust=0")
p2 <- p + theme(axis.title.x=element_text(hjust=0.5)) + xlab("X-axis at hjust=0.5")
p3 <- p + theme(axis.title.x=element_text(hjust=1)) + xlab("X-axis at hjust=1")

library(ggExtra)
align.plots(p1, p2, p3)

inserisci qui la descrizione dell'immagine


Per esplorare ciò che accade con l' vjustallineamento delle etichette degli assi:

DF <- data.frame(x=c("a\na","b","cdefghijk","l"),y=1:4)
p <- ggplot(DF, aes(x,y)) + geom_point()

p1 <- p + theme(axis.text.x=element_text(vjust=0, colour="red")) + 
        xlab("X-axis labels aligned with vjust=0")
p2 <- p + theme(axis.text.x=element_text(vjust=0.5, colour="red")) + 
        xlab("X-axis labels aligned with vjust=0.5")
p3 <- p + theme(axis.text.x=element_text(vjust=1, colour="red")) + 
        xlab("X-axis labels aligned with vjust=1")


library(ggExtra)
align.plots(p1, p2, p3)

inserisci qui la descrizione dell'immagine


1
Quindi, nel caso di angle = 45, quando ho etichette di assi di lunghezza variabile, diciamo da 25 a 5 caratteri, non sono allineati giustificati a destra o a sinistra dei confini della parola. Dai un'occhiata agli assi qui Se dovessi usare l'angolo = 45, come li renderei giustificati a destra e allineati all'asse?
William Gunn,

L'ho provato, e ottengo Error in grid.Call("L_textBounds", as.graphicsAnnot(x$label), x$x, x$y, : Polygon edge not found (zero-width or zero-height?)per vjust = .72e più in alto.
William Gunn,

1
@WilliamGunn Ti suggerisco di pubblicare una nuova domanda con il tuo codice.
Andrie,

1
poiché opt è deprecato, come si regola la posizione del titolo dell'asse?
Cyrus Mohammadian,

1
@CyrusMohammadian, ho modificato questa risposta per lavorare con l'attuale sintassi ggplot2.
Droplet

16

Probabilmente il più definitivo è la Figura B.1 (d) del libro ggplot2, le cui appendici sono disponibili su http://ggplot2.org/book/appendices.pdf .

inserisci qui la descrizione dell'immagine

Tuttavia, non è così semplice. hjuste vjustcome descritto ci sono come funziona geom_texte theme_text(a volte). Un modo di pensarci è quello di pensare a una casella attorno al testo e in cui il punto di riferimento è in relazione a quella casella, in unità relative alla dimensione della casella (e quindi diversa per testi di dimensioni diverse). Un valore hjustdi 0,5 e un valore vjustdi 0,5 centrano la casella sul punto di riferimento. La riduzione hjustsposta la casella a destra di una quantità di volte la larghezza della casella 0.5-hjust. Pertanto hjust=0, quando il bordo sinistro del riquadro si trova nel punto di riferimento. L'aumento hjustsposta la casella a sinistra di una quantità di volte della larghezza della casella hjust-0.5. quandohjust=1, la casella viene spostata di mezza larghezza a sinistra rispetto al centro, posizionando il bordo destro sul punto di riferimento. Se hjust=2il bordo destro della scatola è una larghezza della scatola a sinistra del punto di riferimento (il centro è la 2-0.5=1.5larghezza della scatola a sinistra del punto di riferimento. Per verticale, meno è su e più è giù. Questo è effettivamente ciò che la Figura B.1 (d ) dice, ma estrapola oltre [0,1].

Ma a volte questo non funziona. Per esempio

DF <- data.frame(x=c("a","b","cdefghijk","l"),y=1:4)
p <- ggplot(DF, aes(x,y)) + geom_point()

p + opts(axis.text.x=theme_text(vjust=0))
p + opts(axis.text.x=theme_text(vjust=1))
p + opts(axis.text.x=theme_text(vjust=2))

I tre ultimi grafici sono identici. Non so perché. Inoltre, se il testo viene ruotato, è più complicato. Tener conto di

p + opts(axis.text.x=theme_text(hjust=0, angle=90))
p + opts(axis.text.x=theme_text(hjust=0.5 angle=90))
p + opts(axis.text.x=theme_text(hjust=1, angle=90))
p + opts(axis.text.x=theme_text(hjust=2, angle=90))

Il primo ha le etichette giustificate a sinistra (contro il fondo), il secondo le ha centrate in una scatola in modo che i loro centri siano allineati, e il terzo le ha giustificate a destra (quindi i loro lati destra si allineano vicino all'asse). L'ultimo, beh, non posso spiegarlo in modo coerente. Ha a che fare con la dimensione del testo, la dimensione del testo più largo, e non sono sicuro di cos'altro.


Grazie mille per questo, questo aiuta nel caso in cui angle = 90, ma quello che non capisco è perché la giustificazione a destra delle etichette non funziona più quando invece di angle = 90, uso angle = 45. Capisco il comportamento di angle = 45, hjust = 0, ma angle = 45, hjust = -1 è semplicemente bizzarro.
William Gunn,

Il tuo primo esempio, infatti, funziona. Il motivo per cui pensi che non funzioni è perché tutte le tue etichette hanno la stessa altezza. Riprovare con DF <- data.frame(x=c("a\na","b","cdefghijk","l"),y=1:4)- cioè con una \ninterruzione di riga in uno dei titoli.
Andrie,

@William, penso che @Andrie abbia ragione; hjuste vjustsono definiti solo tra 0 e 1; il comportamento al di fuori di tale intervallo non deve necessariamente avere senso.
Brian Diggs,

@Andrie, hai ragione. Ma faccio ancora fatica a creare un modello mentale coerente nel caso del titolo / testo dell'asse. Per il testo dell'asse, hjust=0allinea il bordo sinistro con il tic; hjust=0.5si concentra sul tic; hjust=1allinea il bordo destro con il tic (casella mobile relativa al punto di riferimento). Ma si vjustallinea all'interno di una scatola delle dimensioni dell'etichetta più alta.
Brian Diggs,

@BrianDiggs Nel caso delle vjustetichette degli assi, tutte le etichette sono contemporaneamente allineate tra loro. Quindi tutti i bordi superiori si allineano quando vjust=1e allo stesso modo tutti i bordi inferiori quando vjust=0. Questo ha perfettamente senso per me.
Andrie,
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.