Apa yang dilakukan hjust dan vjust ketika membuat plot menggunakan ggplot?

159

Setiap kali saya membuat plot menggunakan ggplot, saya menghabiskan sedikit waktu sambil mencoba nilai yang berbeda untuk hjust dan vjust dalam garis seperti

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

untuk mendapatkan label sumbu untuk berbaris di mana label sumbu hampir menyentuh sumbu, dan rata terhadapnya (dibenarkan untuk sumbu, sehingga untuk berbicara). Namun, saya tidak begitu mengerti apa yang sedang terjadi. Seringkali, hjust = 0.5memberikan hasil yang sangat berbeda dari hjust = 0.6, misalnya, bahwa saya belum dapat mengetahuinya hanya dengan bermain-main dengan nilai yang berbeda.

Adakah yang bisa mengarahkan saya ke penjelasan komprehensif tentang cara kerja opsi hjust dan vjust?

William Gunn
sumber
1
Saya memang memberikan contoh spesifik, di komentar untuk jawaban pertama. Rupanya menggunakan angka di luar 0-1 tidak terdefinisi, yang, jika tidak menjelaskan mengapa hjust = -1 memiliki perilaku aneh, setidaknya menjelaskan bahwa aneh itu diharapkan.
William Gunn

Jawaban:

277

Nilai hjustdan vjusthanya didefinisikan antara 0 dan 1:

  • 0 berarti dibenarkan kiri
  • 1 berarti benar

Sumber: ggplot2, Hadley Wickham, halaman 196

(Ya, saya tahu bahwa dalam kebanyakan kasus Anda dapat menggunakannya di luar kisaran ini, tetapi jangan berharap itu berperilaku dengan cara tertentu. Ini di luar spesifikasi.)

hjustmengontrol justifikasi horisontal dan vjustmengontrol justifikasi vertikal.

Contoh harus menjelaskan ini:

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

masukkan deskripsi gambar di sini


Untuk memahami apa yang terjadi ketika Anda mengubah hjustteks sumbu, Anda perlu memahami bahwa perataan horisontal untuk teks sumbu didefinisikan dalam kaitannya bukan dengan sumbu x, tetapi dengan keseluruhan plot (di mana ini termasuk teks sumbu y). (Menurut saya, ini disayangkan. Akan jauh lebih bermanfaat untuk memiliki keberpihakan relatif terhadap sumbu.)

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)

masukkan deskripsi gambar di sini


Untuk menjelajahi apa yang terjadi dengan vjustpenghilangan label sumbu:

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)

masukkan deskripsi gambar di sini

Andrie
sumber
1
Jadi untuk kasus sudut = 45, ketika saya memiliki label sumbu dengan panjang yang bervariasi, katakanlah dari 25 hingga 5 karakter, mereka tidak selaras dibenarkan di sebelah kanan atau kiri batas kata. Lihatlah sumbu di sini. Jika saya menggunakan sudut = 45, bagaimana saya membuatnya benar dan menyiram sumbu?
William Gunn
Saya sudah mencobanya, dan saya mendapatkan Error in grid.Call("L_textBounds", as.graphicsAnnot(x$label), x$x, x$y, : Polygon edge not found (zero-width or zero-height?)untuk vjust = .72dan lebih tinggi.
William Gunn
1
@ WilliamGunn Saya sarankan Anda memposting pertanyaan baru dengan kode Anda.
Andrie
1
karena opt tidak digunakan lagi, bagaimana cara menyesuaikan posisi judul sumbu?
Cyrus Mohammadian
1
@CyrusMohammadian, saya telah mengedit jawaban ini untuk bekerja dengan sintaks ggplot2 saat ini.
Tetesan
16

Mungkin yang paling pasti adalah Gambar B.1 (d) dari buku ggplot2, lampirannya tersedia di http://ggplot2.org/book/appendices.pdf .

masukkan deskripsi gambar di sini

Namun, itu tidak sesederhana itu. hjustdan vjustseperti yang dijelaskan ada cara kerjanya geom_textdan theme_text(kadang-kadang). Salah satu cara untuk memikirkannya adalah dengan memikirkan sebuah kotak di sekitar teks, dan di mana titik referensi terkait dengan kotak itu, dalam satuan relatif terhadap ukuran kotak (dan dengan demikian berbeda untuk teks dengan ukuran yang berbeda). Sebuah hjust0,5 dan vjust0,5 pusat kotak pada titik referensi. Mengurangi hjustmemindahkan kotak tepat dengan jumlah kali lebar kotak 0.5-hjust. Jadi ketika hjust=0, tepi kiri kotak berada di titik referensi. Meningkatkan hjustmemindahkan kotak yang ditinggalkan oleh jumlah kali lebar kotak hjust-0.5. Kapanhjust=1, kotak dipindahkan setengah lebar kotak kiri dari pusat, yang menempatkan tepi kanan pada titik referensi. Jika hjust=2, tepi kanan kotak adalah lebar kotak kiri dari titik referensi (tengah adalah 2-0.5=1.5lebar kotak kiri dari titik referensi. Untuk vertikal, lebih sedikit naik dan lebih banyak turun. Ini secara efektif seperti Gambar B.1 (d ) mengatakan, tetapi meramalkan lebih dari [0,1].

Tapi, terkadang ini tidak berhasil. Sebagai contoh

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

Tiga plot terakhir identik. Saya tidak tahu mengapa itu terjadi. Juga, jika teks diputar, maka itu lebih rumit. Mempertimbangkan

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

Yang pertama memiliki label dibenarkan kiri (terhadap bagian bawah), yang kedua memiliki mereka berpusat di beberapa kotak sehingga pusat mereka berbaris, dan yang ketiga memiliki mereka dibenarkan (sehingga sisi kanan mereka berbaris di sebelah sumbu). Yang terakhir, yah, saya tidak bisa menjelaskan dengan cara yang koheren. Ini ada hubungannya dengan ukuran teks, ukuran teks terluas, dan saya tidak yakin apa lagi.

Brian Diggs
sumber
Terima kasih banyak untuk ini, ini membantu untuk kasus di mana sudut = 90, tetapi apa yang saya tidak dapatkan adalah mengapa pembenaran yang tepat dari label tidak berfungsi lagi ketika alih-alih sudut = 90, saya menggunakan sudut = 45. Saya mengerti perilaku angle = 45, hjust = 0, tetapi angle = 45, hjust = -1 hanya aneh.
William Gunn
Contoh pertama Anda ternyata bekerja. Alasan Anda berpikir itu tidak berhasil adalah karena semua label Anda memiliki ketinggian yang sama. Coba lagi dengan DF <- data.frame(x=c("a\na","b","cdefghijk","l"),y=1:4)- yaitu dengan \nlinebreak di salah satu judul.
Andrie
@ William, saya pikir @ Andrie sudah benar; hjustdan vjusthanya didefinisikan antara 0 dan 1; perilaku di luar rentang itu tidak perlu masuk akal.
Brian Diggs
@ Andrie, Anda benar. Tetapi saya masih kesulitan membuat model mental yang koheren dalam judul / kasus teks poros. Untuk teks sumbu, hjust=0sejajarkan tepi kiri dengan tic; hjust=0.5berpusat pada tic; hjust=1sejajarkan tepi kanan dengan tic (kotak bergerak relatif terhadap titik referensi). Tapi vjustsejajarkan dalam kotak ukuran label tertinggi.
Brian Diggs
@BrianDiggs Dalam kasus vjustlabel sumbu, semua label secara bersamaan disejajarkan satu sama lain. Jadi semua tepi atas sejajarkan kapan vjust=1dan juga semua tepi bawah kapan vjust=0. Ini masuk akal bagi saya.
Andrie