I have a ggplot object. I would like to add some text with annotate()
, and I would like to specify the coordinates of the text in npc units. Is this possible?
As of 'ggpmisc' (>= 0.3.6) the following code works as expected (in CRAN as of 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")
Personally, I would use Baptiste's method but wrapped in a custom function to make it less clunky:
annotate_npc <- function(label, x, y, ...)
{
ggplot2::annotation_custom(grid::textGrob(
x = unit(x, "npc"), y = unit(y, "npc"), label = label, ...))
}
Which allows you to do:
p + annotate_npc("hello", 0.5, 0.5)
Note this will always draw your annotation in the npc space of the viewport of each panel in the plot, (i.e. relative to the gray shaded area rather than the whole plotting window) which makes it handy for facets. If you want to draw your annotation in absolute npc co-ordinates (so you have the option of plotting outside of the panel's viewport), your two options are:
coord_cartesian(clip = "off")
and reverse engineer the x, y co-ordinates from the given npc co-ordinates before using annotate
. This is complicated but possiblegrid
. This is far easier, but has the downside that the annotation has to be drawn over the plot rather than being part of the plot itself. You could do that like this:annotate_npc_abs <- function(label, x, y, ...)
{
grid::grid.draw(grid::textGrob(
label, x = unit(x, "npc"), y = unit(y, "npc"), ...))
}
And the syntax would be a little different:
p
annotate_npc_abs("hello", 0.05, 0.75)