sử dụng đơn vị npc trong annotate ()
Tôi có một đối tượng ggplot. Tôi muốn thêm một số văn bản với annotate()và tôi muốn chỉ định tọa độ của văn bản theo đơn vị npc. Điều này có khả thi không?
Ví dụ tối thiểu này minh họa cách văn bản được định vị thông thường với annotate():
library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p + annotate("text", x = 30, y = 4.5, label = "hello")
Tôi muốn đạt được hiệu quả tương tự, nhưng thay vì chỉ định xvà ytheo tọa độ gốc, tôi muốn chỉ định chúng bằng tọa độ npc. Đối với mục đích của ví dụ này, tôi không lo lắng về việc dịch chính xác x = 30và y = 4.5sang các đơn vị npc. Tôi chỉ muốn biết liệu có thể sử dụng các đơn vị npc hay không annotate().
Có hai chiến lược liên quan, nhưng chúng không hoàn toàn thỏa đáng:
Người ta có thể sử dụng các đơn vị npc bằng cách chỉ định chúng thành, chẳng hạn
grid::textGrob(),. Và sau đó người ta có thể đặt háng vớiannotation_custom(), như trong câu trả lời này của @baptiste . Nhưng giải pháp này hơi rườm rà hơn tôi muốn.Gói "ggpmisc" bao gồm
geom_text_npc(). Nhưng nó vẫn chưa hoạt động vớiannotate(). Đó là,annotate("text_npc", ...)dường như không hoạt động. [Chỉnh sửa: nó hiện hoạt động. Xem thông điệp của Pedro Aphalo bên dưới.]
Ngoài ra còn có nhiều bài viết liên quan. Đặc biệt, Greg Snow đã đề xuất sử dụng lưới để tạo một khung nhìn với các kích thước pvà sau đó chú thích cho khung nhìn đó. Và @teunbrand đã đề xuất một phương pháp yêu cầu chuyển đổi pthành đối tượng "gtable" (với ggplotGrob()) và sau đó vẽ đối tượng "gtable" đó. Một trong hai chiến lược này có thể được điều chỉnh cho phù hợp với mục đích của tôi. Nhưng có cách nào đơn giản hơn để sử dụng tọa độ npc với annotate()không?
Trả lời
Cá nhân tôi sẽ sử dụng phương pháp của Baptiste nhưng được bao bọc trong một hàm tùy chỉnh để làm cho nó bớt rắc rối hơn:
annotate_npc <- function(label, x, y, ...)
{
ggplot2::annotation_custom(grid::textGrob(
x = unit(x, "npc"), y = unit(y, "npc"), label = label, ...))
}
Điều này cho phép bạn làm:
p + annotate_npc("hello", 0.5, 0.5)
Lưu ý rằng điều này sẽ luôn vẽ chú thích của bạn trong không gian npc của khung nhìn của mỗi bảng điều khiển trong biểu đồ, (tức là liên quan đến vùng bóng mờ màu xám chứ không phải toàn bộ cửa sổ vẽ biểu đồ), điều này rất tiện lợi cho các khía cạnh. Nếu bạn muốn vẽ chú thích của mình trong tọa độ npc tuyệt đối (vì vậy bạn có tùy chọn vẽ biểu đồ bên ngoài khung nhìn của bảng điều khiển), hai tùy chọn của bạn là:
- Tắt bớt
coord_cartesian(clip = "off")và đảo ngược thiết kế tọa độ x, y từ tọa độ npc đã cho trước khi sử dụngannotate. Điều này phức tạp nhưng có thể - Vẽ nó ngay lập tức khi sử dụng
grid. Điều này dễ dàng hơn nhiều, nhưng có nhược điểm là chú thích phải được vẽ trên cốt truyện hơn là một phần của chính cốt truyện. Bạn có thể làm như thế này:
annotate_npc_abs <- function(label, x, y, ...)
{
grid::grid.draw(grid::textGrob(
label, x = unit(x, "npc"), y = unit(y, "npc"), ...))
}
Và cú pháp sẽ khác một chút:
p
annotate_npc_abs("hello", 0.05, 0.75)
Kể từ 'ggpmisc' (> = 0.3.6), mã sau hoạt động như mong đợi (trong CRAN kể từ 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")