Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling of aes() mappings that do not refer to the layer data #3359

Closed
paleolimbot opened this issue Jun 7, 2019 · 1 comment
Closed

Handling of aes() mappings that do not refer to the layer data #3359

paleolimbot opened this issue Jun 7, 2019 · 1 comment

Comments

@paleolimbot
Copy link
Member

There are a number of issues that have been opened expressing surprise at the handling of Layers where aes() does not refer to the data and the data is not specified.

library(ggplot2)
ggplot(data.frame(x = 1:5)) + 
  geom_text(aes(x = 1, y = 1, label = "annotation"))

This plot contains 5 copies of the "annotation" label, since the geom_text() layer inherits the plot data, and the aesthetics are recycled to the length of the layer data (if they are length 1). This usually only noticed for partially transparent objects (#2829, #2529, #2790), but has also caused errors in geom_boxplot() (#3316).

This is usually caused by slightly spurious ggplot2 usage by users who do not create and map a data frame but instead wire vectors directly into one or more layers directly by aes(). The workarounds are:

  • Actually create a data frame and map it. This is obviously preferred but can get verbose for something like geom_boxplot() with stat = "identity", where even aes_all(c("ymin", "lower", "middle", "upper", "ymax")) is pretty verbose.
  • Use annotate(), although this doesn't work with facets when there are non-position aesthetics with a length != 1 ( Annotation breaks with facets #3305 (comment) ), and doesn't always train the position scales properly for position aesthetics that are not (x|y), (x|y)min, or (x|y)max (Consolidate definition of position aesthetics #3342).
  • For the layer data, pass a non-null value for which ggplot2:::empty() returns TRUE (e.g., data = data.frame()). This keeps the layer from inheriting the plot data, since there is no inherit.data argument of a plot layer, although it doesn't really make sense.

I think there are some options to discourage this practice and/or make it less verbose to do the right thing.

  • Add an inherit.data argument that can be set to FALSE, such that one can safely and predictably pass vectors into aes().
  • Make the mapping a function of the data and make a function that returns an automapped data frame. We already sort of do this for geom_sf(), where we automatically map the geometry column for data of class sf. Then, one could do something like geom_text(data = mapped_df(x = 1, y = 1, label = "annotation")), which would generate the appropriate mapping.
  • Fix annotate() so that it works with all position aesthetics and with facets.
  • Warn when users supply a mapping that does not refer to data (this was recently vetoed, see Warn about discouraged aes() usage during plot build #3346)
@teunbrand
Copy link
Collaborator

In #5256 we added warnings for such cases, so I'm going to consider this completed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants