1

Is there a way to specify that a custom_annotation only applies to one facet of a ggplot?

For example, if I run the following code

library(tidyverse)
library(grid)

text_grob=grobTree(textGrob("text",x=0.5, y=0.6, rot=90,
    gp=gpar(col="red")))

ggplot(mtcars, aes(x=mpg, y =drat))+
  geom_point() +
  facet_wrap(~cyl) +
  annotation_custom(overrep_grob)

I get this

enter image description here

How can I only keep the rightmost red "text" annotation and not add the "text" annotation to the first two facets? Note I can't use geom_text or annotate because I need to make use of textGrob's relative text positioning

Ajjit Narayanan
  • 632
  • 2
  • 8
  • 18
  • `mtcars` is a built in dataset. So the code above is already a reprex. Just run it in your R terminal and you will get the plot. You might have to install `tidyverse` and `grid` if you don't have them though – Ajjit Narayanan Aug 15 '18 at 20:28
  • sorry, did not catch that. – Suhas Hegde Aug 15 '18 at 20:30
  • See [here](https://stackoverflow.com/questions/32807665/removing-one-tablegrob-when-applied-to-a-box-plot-with-a-facet-wrap/32832732#32832732) for a modified version of `annotation_custom` that allows the panel to be specified – Sandy Muspratt Aug 15 '18 at 22:18
  • Thats a very elegant solution! Thanks – Ajjit Narayanan Aug 16 '18 at 15:55

2 Answers2

3

egg has geom_custom,

library(ggplot2)
library(grid)
library(egg)

d = data.frame(cyl=6, drat = 4, mpg = 15)
d$grob <- list(textGrob("text",rot=90, hjust = 0, gp=gpar(col="red")))

ggplot(mtcars, aes(x=mpg, y=drat))+
  geom_point() +
  facet_wrap(~cyl) +
  geom_custom(data = d, aes(data = grob), grob_fun = identity)
3

You could also do this using geom_text by calculating the relative position of the text needed. Note that here, the relative position is slightly different than the one you use above because here I define the relative position as some proportion of the dynamic range. You can choose a different value for rel to get the position you need. I find that this way makes the positioning less arbitrary.

library(tidyverse)

rel_pos <- function(.data, var, rel){
  var <- enquo(var)
  .data %>% 
    summarise(x = sum(max(!!var), min(!!var))* rel) %>% .[1, "x"]
}

my_text <- data_frame(mpg = rel_pos(mtcars, mpg, 0.5), 
                      drat = rel_pos(mtcars, drat, 0.6) , 
                      cyl = 8, lab = "text")

ggplot(mtcars, aes(x=mpg, y =drat))+
  geom_point() +
  facet_wrap(~cyl)+
  geom_text(data = my_text, aes(label = lab), color = "red", angle = 90)

Created on 2018-08-15 by the reprex package (v0.2.0).

AndS.
  • 7,748
  • 2
  • 12
  • 17