2

我有一个 ggplot 对象。我想添加一些文本annotate(),并且我想以 npc 单位指定文本的坐标。这可能吗?

这个最小的例子演示了文本通常是如何定位的annotate()

library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p + annotate("text", x = 30, y = 4.5, label = "hello")

我想达到同样的效果,但是我不想在原生坐标中指定xand ,而是y想用 npc 坐标来指定它们。出于本示例的目的,我并不担心准确地转换x = 30y = 4.5npc 单位。我只是想知道是否可以使用 npc 单位annotate()

有两种相关的策略,但它们并不完全令人满意:

  1. 可以通过将 npc 单位指定为grid::textGrob(). 然后可以将grob 放在annotation_custom(),就像@baptiste 的这个答案一样。但是这个解决方案比我想要的要麻烦一些。

  2. “ggpmisc”包包括geom_text_npc(). 但它还不能annotate(). 也就是说,annotate("text_npc", ...)似乎不起作用。[编辑:它现在可以工作了。请参阅下面 Pedro Aphalo 的消息。]

还有很多相关的帖子。特别是,Greg Snow 建议使用网格来创建具有尺寸的视口p,然后对该视口进行注释。@teunbrand建议了一种方法,该方法需要转换p为“gtable”对象(使用ggplotGrob()),然后绘制该“gtable”对象。这些策略中的任何一个都可能适合我的目的。但是有没有更直接的方法来使用 npc 坐标annotate()

4

2 回答 2

6

就个人而言,我会使用 Baptiste 的方法,但将其包裹在自定义函数中以使其不那么笨重:

annotate_npc <- function(label, x, y, ...)
{
  ggplot2::annotation_custom(grid::textGrob(
    x = unit(x, "npc"), y = unit(y, "npc"), label = label, ...))
}

这允许您执行以下操作:

p + annotate_npc("hello", 0.5, 0.5)

在此处输入图像描述

请注意,这将始终在绘图中每个面板的视口的 npc 空间中绘制您的注释(即相对于灰色阴影区域而不是整个绘图窗口),这使得它对构面很方便。如果您想以绝对 npc 坐标绘制注释(因此您可以选择在面板视口之外进行绘图),您的两个选项是:

  1. coord_cartesian(clip = "off")在使用annotate. 这很复杂但可能
  2. 直接用grid. 这要容易得多,但缺点是必须在绘图上绘制注释,而不是作为绘图本身的一部分。你可以这样做:
annotate_npc_abs <- function(label, x, y, ...) 
{
  grid::grid.draw(grid::textGrob(
    label, x = unit(x, "npc"), y = unit(y, "npc"), ...))
}

语法会有点不同:

p 
annotate_npc_abs("hello", 0.05, 0.75)

在此处输入图像描述

于 2020-09-04T13:31:22.710 回答
2

从 'ggpmisc' (>= 0.3.6) 开始,以下代码按预期工作(截至 2020 年 9 月 10 日在 CRAN 中)。

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")
于 2020-09-10T17:20:49.597 回答