Skip to content

Better support for custom color and fill aesthetics? #2345

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
clauswilke opened this issue Nov 18, 2017 · 4 comments
Closed

Better support for custom color and fill aesthetics? #2345

clauswilke opened this issue Nov 18, 2017 · 4 comments
Labels
feature a feature request or enhancement scales 🐍

Comments

@clauswilke
Copy link
Member

Hello,

I'm wondering whether it would be possible to better support custom color and fill aesthetics. What I mean are cases where maybe we want two separate color mappings in the same geom, e.g. line_color and point_color. With the current ggplot2, if I create such aesthetics, I can't take advantage of any of the existing color scales. But with a few small changes, I think this would be possible.

First, to demonstrate that this is a real situation, some example code from ggridges:

cols = c("#E69F00", "#56B4E9", "#009E73")
cols_dark = c('#C18511', '#289ACF', '#0D8561')
ggplot(iris, aes(x=Sepal.Length, y=Species, fill = Species)) +
  geom_density_ridges(aes(point_color = Species), alpha = .2, jittered_points = TRUE) +
  scale_fill_manual(values = cols, guide = "none") + scale_y_discrete(expand = c(0.01, 0)) +
  ggplot2:::manual_scale("point_color", values = cols_dark, guide = "none") +
  theme_ridges(grid = FALSE, center = TRUE)

screen shot 2017-11-18 at 3 20 39 pm

In this example, everything needs to be drawn at once in one geom, because the filled areas and solid lines can overlap the points. But, I want to be able to specify line colors and point colors separately, and the point colors should also be different from the fill colors. The only way I see to solve the problem is to add a point_color aesthetic.

My code example brings up one immediate and easy to fix issue: ggplot2 doesn't export manual_scale, but it's what is needed here to make this example work without too much effort. Second, it would be helpful if the various existing color scales took an optional aesthetics argument that can be used to override the aesthetics in the function name. While this may sound a bit strange, the resulting code would be quite legible and look reasonable. For example, using the default hue color scale for fill and also applying it to the points might look like this:

ggplot(iris, aes(x=Sepal.Length, y=Species, fill = Species)) +
  geom_density_ridges(aes(point_color = Species), alpha = .2, jittered_points = TRUE) +
  scale_color_hue(aesthetics = "point_color") + scale_y_discrete(expand = c(0.01, 0)) +
  theme_ridges(grid = FALSE, center = TRUE)

So, in summary, I'm making the following requests:

  1. Export manual_scale
  2. Add optional aesthetics parameter to all existing color scales

I'd be happy to work on a pull request if you're willing to consider these changes.

@clauswilke
Copy link
Member Author

clauswilke commented Nov 19, 2017

Some more thoughts on this: I now think all scales should have an optional aesthetics parameter, not just color scales. The same issue exists, e.g., with scale_shape(). And I don't think it would make sense to implement separate scales functions that don't contain the aesthetic in their name, as in scale_hue(), because then one quickly runs into trouble. E.g., the generic version of scale_shape() would be scale(), which obviously doesn't make sense.

I think it's important to realize that the words "color", "shape", "size" etc. actually serve two distinct purposes in the scale names: First, they define what type of a scale we're dealing with (a color scale, or a shape scale, etc). Second, they name the specific aesthetic for which the scale works. Those two purposes are currently tightly coupled in ggplot2, but they don't have to be.

For example, it would be perfectly reasonable to always implement color scales first as scale_color_* and then provide fill scales simply by calling the color version with aesthetics = "fill", as in:

scale_fill_hue <- function(...) scale_color_hue(..., aesthetics = "fill")

@clauswilke
Copy link
Member Author

After having worked with this for about a day now, I have found one other issue: The default guide function for continuous color scales, guide_colorbar, does not want to work with aesthetics it doesn't know. The guide_legend function does not have this limitation. Thus, I have been able to draw legends for aesthetics point_size, point_shape, and discrete point_color and point_fill, but not for continuous point_color or point_fill.

@clauswilke
Copy link
Member Author

I'm closing this because main primary issues have been addressed with #2555. I'll open a new issue to collect thoughts for future directions.

@lock
Copy link

lock bot commented Nov 6, 2018

This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/

@lock lock bot locked and limited conversation to collaborators Nov 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature a feature request or enhancement scales 🐍
Projects
None yet
Development

No branches or pull requests

2 participants