MattCowgill / ggannotate

Interactively annotate ggplots
Other
309 stars 20 forks source link

Consider using annotate() instead of geom_text() / geom_label() #29

Closed jhelvy closed 4 years ago

jhelvy commented 4 years ago

When the user adds a label, I would suggest using annotate(). This enables you to avoid having to create a data frame and mapping the aesthetics. Instead you just give it the coordinates and label, along with all the other label options. You can still set text or label annotations by using annotate(geom = "text") or annotate(geom = "label"). The returned code is just a little more parsimonious than what you get with geom_text() or geom_label(). I usually only use those when I'm mapping multiple labels from a data frame.

I'd be happy to implement this one myself if you want.

MattCowgill commented 4 years ago

Hi @jhelvy, an initial version of the package did actually use annotate(), until I realised that you can't annotate a single facet using annotate().

For example, say I have this plot and want to annotate just in the middle panel:

library(ggplot2)

p <- ggplot(mtcars,
            aes(x = wt, y = mpg)) +
  geom_point() +
  facet_wrap(~cyl)

p

If I annotate using annotate(), the annotation appears on each panel:


p +
  annotate("text", x = 4, y = 30, label = "something")

There's no way to pass along the facet variable and level:


p +
  annotate("text", x = 4, y = 30, label = "something", cyl = 6)
#> Warning: Ignoring unknown parameters: cyl

Whereas by supplying a data frame to the geom_*() function, I can include the facet variable and level, as in:


p + 
  geom_text(data = data.frame(x = 4, y = 30, label = "something",
                              cyl = 6),
            aes(x = x, y = y, label = label))

This is somewhat more verbose, but for me this is a price worth paying for the ability to annotate individual facets rather than have my annotation repeated in each panel. Please note also that in a recent update of ggannotate I have compressed the output that is returned from the Shiny app -- it now only returns parameters that differ from the geom default. This reduces the number of lines of code that are returned considerably.

I also intend to 'collect like terms' when users can add multiple annotations of the same type. For example, if they add multiple 'text' annotations, this will be done with a single geom_text() call.

Created on 2020-08-01 by the reprex package (v0.3.0)

jhelvy commented 4 years ago

Ah...I completely forgot about faceting. The output suppression too is a nice feature.