gunakan unit npc di annotate ()
Saya memiliki objek ggplot. Saya ingin menambahkan beberapa teks dengan annotate(), dan saya ingin menentukan koordinat teks dalam unit npc. Apakah ini mungkin?
Contoh minimal ini menunjukkan bagaimana teks biasanya diposisikan dengan annotate():
library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p + annotate("text", x = 30, y = 4.5, label = "hello")
Saya ingin mencapai efek yang sama, tetapi alih-alih menentukan xdan ydalam koordinat asli, saya ingin menentukannya dengan koordinat npc. Untuk tujuan contoh ini, saya tidak khawatir tentang menerjemahkan x = 30dan y = 4.5menjadi unit npc. Saya hanya ingin tahu apakah unit npc dapat digunakan annotate()sama sekali.
Ada dua strategi terkait, tetapi tidak sepenuhnya memuaskan:
Seseorang dapat menggunakan unit npc dengan menspesifikasikannya menjadi, katakanlah
grid::textGrob(),. Dan seseorang kemudian dapat menempatkan grob denganannotation_custom(), seperti dalam jawaban ini oleh @baptiste . Tetapi solusi ini sedikit lebih rumit daripada yang saya inginkan.Paket "ggpmisc" termasuk
geom_text_npc(). Tapi itu belum bekerja denganannotate(). Artinya,annotate("text_npc", ...)sepertinya tidak berhasil. [Sunting: sekarang bekerja. Lihat pesan Pedro Aphalo di bawah ini.]
Ada juga banyak postingan terkait. Secara khusus, Greg Snow telah menyarankan penggunaan kisi untuk membuat area pandang dengan dimensi pdan kemudian menjelaskan area pandang tersebut. Dan @teunbrand telah menyarankan metode yang memerlukan konversi pke objek "gtable" (dengan ggplotGrob()) dan kemudian menggambar objek "gtable" itu. Salah satu dari strategi ini mungkin dapat disesuaikan dengan tujuan saya. Tetapi apakah ada cara yang lebih mudah untuk menggunakan koordinat npc annotate()?
Jawaban
Secara pribadi, saya akan menggunakan metode Baptiste tetapi dibungkus dengan fungsi khusus agar tidak terlalu kikuk:
annotate_npc <- function(label, x, y, ...)
{
ggplot2::annotation_custom(grid::textGrob(
x = unit(x, "npc"), y = unit(y, "npc"), label = label, ...))
}
Yang memungkinkan Anda melakukan:
p + annotate_npc("hello", 0.5, 0.5)
Perhatikan bahwa ini akan selalu menggambar anotasi Anda di ruang npc viewport setiap panel di plot, (yaitu relatif terhadap area berbayang abu-abu daripada seluruh jendela plot) yang membuatnya berguna untuk facet. Jika Anda ingin menggambar anotasi Anda dalam koordinat npc absolut (sehingga Anda memiliki opsi untuk membuat plot di luar area pandang panel), dua opsi Anda adalah:
- Matikan kliping dengan
coord_cartesian(clip = "off")dan balikkan koordinat x, y dari koordinat npc yang diberikan sebelum menggunakanannotate. Ini rumit tapi mungkin - Gambarlah langsung saat menggunakan
grid. Ini jauh lebih mudah, tetapi memiliki sisi negatifnya yaitu anotasi harus digambar di atas plot daripada menjadi bagian dari plot itu sendiri. Anda bisa melakukannya seperti ini:
annotate_npc_abs <- function(label, x, y, ...)
{
grid::grid.draw(grid::textGrob(
label, x = unit(x, "npc"), y = unit(y, "npc"), ...))
}
Dan sintaksnya akan sedikit berbeda:
p
annotate_npc_abs("hello", 0.05, 0.75)
Mulai 'ggpmisc' (> = 0.3.6) kode berikut berfungsi seperti yang diharapkan (dalam CRAN mulai 2020-09-10).
library(ggpmisc)
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
# default justification is "inward"
p + annotate("text_npc", npcx = 0.8, npcy = 0.75, label = "hello")
# same justification as default for "geom_text()"
p + annotate("text_npc", npcx = 0.8, npcy = 0.75, label = "hello",
hjust = "center", vjust = "middle")