Skip to content

geom_hline: inherit.aes is always FALSE #426

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

Closed
wch opened this issue Mar 4, 2012 · 5 comments
Closed

geom_hline: inherit.aes is always FALSE #426

wch opened this issue Mar 4, 2012 · 5 comments
Milestone

Comments

@wch
Copy link
Member

wch commented Mar 4, 2012

For geom_hline, vline, and abline, inherit.aes is always FALSE. I can see an advantage: when drawing data from a different data frame, it won't attempt to map possibly nonexistent variables to x and y. However, there are a few drawbacks:

  • Behavior is inconsistent with other geoms.
  • Aesthetics such as colour and yintercept can't be inherited and must be respecified for the geom. This is especially strange if the values are drawn from the original data frame.
mtcar_means <- ddply(mtcars, .(cyl), summarise, mpg = mean(mpg))
# cyl      mpg
#   4 26.66364
#   6 19.74286
#   8 15.10000

# All black lines
ggplot(mtcars, aes(x=disp, y=mpg, colour=factor(cyl))) + geom_point() +
  geom_hline(aes(yintercept=mpg), data=mtcar_means)

# Need to respecify mapping to get colored lines
ggplot(mtcars, aes(x=disp, y=mpg, colour=factor(cyl))) + geom_point() +
  geom_hline(aes(yintercept=mpg, colour=factor(cyl)), data=mtcar_means)

It appears impossible to set inherit.aes=TRUE. I think this is because the value is hard-coded in the $new functions for each geom. If it is indeed desired to have them not inherit by default, I think a better way is to set the default value inherit.aes=FALSE, instead of hard-coding it.

# Can't set inherit.aes=TRUE
ggplot(mtcars, aes(x=disp, y=mpg, colour=factor(cyl))) + geom_point() +
  geom_hline(aes(yintercept=mpg), data=mtcar_means, inherit.aes=TRUE)
# Error in get(x, envir = this, inherits = inh)(this, ...) :
#   formal argument "inherit.aes" matched by multiple actual arguments
@hadley
Copy link
Member

hadley commented Mar 5, 2012

I think the best solution is to split geom_hline into geom_hline for when you want to map the position of the line to a variable in your data and annotate_hline for when you have a vector of positions.

@wch
Copy link
Member Author

wch commented Mar 5, 2012

Could we just use annotate to do this? I tried running this code, but it doesn't work:

ggplot(mtcars, aes(x=disp, y=mpg, colour=factor(cyl))) + geom_point() +
  annotate("hline", yintercept=20)
# Error in is.unit(y1) : object 'yend' not found

I think it has something to do with GeomHline$new not getting called when you use annotate().

@hadley
Copy link
Member

hadley commented Mar 5, 2012

Yes, but I think it needs some re-writing of the geom_hline code because it tries to automatically figure out if you want a annotation or a data-based geom.

@BrianDiggs
Copy link
Contributor

Here is another issue which comes about because inherit.aes is fixed to FALSE. If xintercept is specified as a function (or character name of a function), then the mapping must be respecified so that the summary function can find the data.

Consider:

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

p + geom_vline(xintercept=3)
p + geom_vline(xintercept=mean)
p + geom_vline(xintercept=mean, inherit.aes=TRUE)
p + geom_vline(xintercept=mean, aes(x=wt))

The first works as expected. The second gives

> p + geom_vline(xintercept=mean)
Warning messages:
1: In mean.default(data[[var]]) :
  argument is not numeric or logical: returning NA
2: Removed 1 rows containing missing values (geom_segment). 

The third gives

> p + geom_vline(xintercept=mean, inherit.aes=TRUE)
Error in get(x, envir = this, inherits = inh)(this, ...) : 
  formal argument "inherit.aes" matched by multiple actual arguments

The forth works.

The pattern is identical for geom_hline (substituting yintercept for xintercept):

p + geom_hline(yintercept=23)
p + geom_hline(yintercept=mean)
p + geom_hline(yintercept=mean, inherit.aes=TRUE)
p + geom_hline(yintercept=mean, aes(y=mpg))

It is worth noting that using stat_vine or stat_hline instead of the geom_ versions work as expected in all cases because the stat_ versions do not have inherit.aes set to FALSE

# all work without error
p + stat_vline(xintercept=3)
p + stat_vline(xintercept=mean)
p + stat_vline(xintercept=mean, inherit.aes=TRUE)
p + stat_vline(xintercept=mean, aes(x=wt))

p + stat_hline(yintercept=23)
p + stat_hline(yintercept=mean)
p + stat_hline(yintercept=mean, inherit.aes=TRUE)
p + stat_hline(yintercept=mean, aes(y=mpg))

This comment was inspired by the StackOverflow question http://stackoverflow.com/q/18786161/892313

@hadley
Copy link
Member

hadley commented Feb 24, 2014

This sounds like a great feature, but unfortunately we don't currently have the development bandwidth to support it. If you'd like to submit a pull request that implements this feature, please follow the instructions in the development vignette.

@hadley hadley closed this as completed Feb 24, 2014
has2k1 added a commit to has2k1/plotnine that referenced this issue Apr 25, 2017
- These geoms still have same type of issues as ggplot2.
  tidyverse/ggplot2#426
  This is a badge-of-honor :)
@lock lock bot locked as resolved and limited conversation to collaborators Jun 20, 2018
mnazarov added a commit to mnazarov/ggplot2 that referenced this issue Aug 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants