Skip to content

Feature request: discrete color scales that don't fail with too few colors #2428

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
jnolis opened this issue Jan 29, 2018 · 3 comments
Closed

Comments

@jnolis
Copy link

jnolis commented Jan 29, 2018

When you make a chart that uses many discrete colors, you never have to worry about the number of colors if you use the default colors.

require(ggplot2)
ggplot(data.frame(x=letters[1:26],y=runif(26)),aes(x=x,y=y,fill=x))+geom_col()

image

If you want to use your own colors (for instance, if you have company colors), it's easy to use a scale_manual to set the colors

company_colors <-c("#E50000", "#008A8A", "#AF0076", "#E56800", "#1717A0", "#E5AC00", "#00B700")

ggplot(data.frame(x=letters[1:7],y=runif(7)),aes(x=x,y=y,fill=x)) +
geom_col() +
scale_fill_manual(values=company_colors)

image

However, when you use this method you'll run into trouble if your number of needed colors is greater than the length of your color vector. This can be especially problematic because you generally want to just say "always use my company colors so I don't worry about it."

ggplot(data.frame(x=letters[1:26],y=runif(26)),aes(x=x,y=y,fill=x)) +
geom_col() +
scale_fill_manual(values=company_colors)
Error: Insufficient values in manual scale. 26 needed but only 7 provided.

One solution to this is to create a function that makes a desired length vector of colors based on your existing ones:

make_color_vector <- function(desired_length,base_colors){
  if(desired_length <= length(base_colors)){
    base_colors[1:n]
  } else {
    ramp_to_colors <- function(color,amount){
      if(amount > 1){
        current_color <- color
        return_colors <- c()
        for(a in 1:(amount)){
          return_colors <- c(return_colors,current_color)
          current_color <- grDevices::colorRampPalette(c(current_color,"#222222"))(4)[2]
        }
        return_colors
      } else {
        color
      }
    }
    iterations <- ceiling(desired_length/length(base_colors))
    as.vector(do.call(rbind,lapply(base_colors,function(x) ramp_to_colors(x,iterations))))[1:desired_length]
  }
}

ggplot(data.frame(x=letters[1:26],y=runif(26)),aes(x=x,y=y,fill=x)) +
geom_col() +
scale_fill_manual(values = make_color_vector(26, company_colors))

But the downside to this is you still need to keep track of how many colors you need.

This seems like something that could be added to ggplot2 without breaking anything! One solution would be to let scale_fill_manual take a function which takes an integer as an input and returned the desired number of colors (rather than just a vector of colors). This feels similar to how some of the labels and breaks parameters work for scales. You could include the "make_color_vector" function within ggplot2 itself, or leave other people to make their own. Improving this functionality seems like it would help other packages downstream (like ggthemr, which sets default themes but breaks if your custom theme doesn't have enough colors).

I'm happy to help write the code to do this, but unfortunately I'm struggling to figure out where in the ggplot2 code base I would make these changes.

Thank you!

@has2k1
Copy link
Contributor

has2k1 commented Jan 29, 2018

This seems like something that could be added to ggplot2 ...

The right place is https://github.com/hadley/scales.

@jnolis
Copy link
Author

jnolis commented Jan 29, 2018

Closing and moving to scales

@jnolis jnolis closed this as completed Jan 29, 2018
@lock
Copy link

lock bot commented Jul 28, 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 Jul 28, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants