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

Generate seed for distinguishable_colors #18

Closed
tbreloff opened this issue Sep 18, 2015 · 14 comments
Closed

Generate seed for distinguishable_colors #18

tbreloff opened this issue Sep 18, 2015 · 14 comments

Comments

@tbreloff
Copy link
Member

As part of Plots, I let the user specify both a background color and series colors. Defaults are colorant"white" for the background and ':auto' for the series colors. Right now for :auto I choose from this pre-generated list:

const COLORS = distinguishable_colors(20)

However it would be ideal if those colors could be chosen on-the-fly, to be distiguishable both from the background color and other previous colors (i.e. not a hardcoded 20-length vector). This way if I choose a black background, I don't plot a black line as the default.

Does this exist within Colors? I feel like the pieces are there, I'm just not sure the right way to access them.

@timholy
Copy link
Member

timholy commented Sep 18, 2015

Yeah, it's there. Just pre-populate the seed input with the colors you don't want it to pick.

@stevengj
Copy link
Contributor

Yes and no. e.g. if I want a few colors very different from black, I can do:
image
However, it doesn't treat the seed as "privileged" in any way, so if you generate enough colors you will eventually get one close to the seed:
image

@tbreloff
Copy link
Member Author

Is there an algorithmic equivalent to: "background color is dark, so pick 10 distiguishable colors that are light", or can you somehow weight the importance of the difference between colors? i.e. I want a new color that is really different than the first color, but only a little different from the rest.

@dcjones
Copy link
Contributor

dcjones commented Sep 18, 2015

Probably the way to do that would be to extend distinguishable_colors to work with an arbitrary color difference function (it's hard coded to CIEDE2000 now), then write your own difference function that weights things.

@tbreloff
Copy link
Member Author

Ok thanks @dcjones. Assuming the weighted version isn't already implemented, I'll add it to my list.

@m-lohmann
Copy link

It’s interesting that distinguishable colors produces two blue colors
that don’t appear very distinguishable from each other at all, looking
at the image.

On 18.09.2015 18:26, Steven G. Johnson wrote:

Yes and no. e.g. if I want a few colors very different from black, I can do:
image
https://cloud.githubusercontent.com/assets/2913679/9964787/46100622-5e00-11e5-8c45-be745066dcd3.png
However, it doesn't treat the seed as "privileged" in any way, so if you
generate enough colors you will eventually get one close to the seed:
image
https://cloud.githubusercontent.com/assets/2913679/9964828/81bd9162-5e00-11e5-84f5-066dbe7f3503.png


Reply to this email directly or view it on GitHub
#18 (comment).

@tbreloff
Copy link
Member Author

Using distinguishable_colors with the background color as the seed, here's what I get:

using Plots
subplot(cumsum(randn(10,40),1), w=5, bg=[:white,:black,:grey,:orange], n=4)

tmp

This is pretty good, but there are some colors which are way too close to the background. I'll look into a weighted algorithm. Thanks for the help.

@timholy
Copy link
Member

timholy commented Sep 18, 2015

You may also want to try the old algorithm in Color.jl. It's possible that my performance improvement was "more" than just performance-related...

@tbreloff
Copy link
Member Author

I copy/pasted the function from Color.jl, and it worked if I changed {T<:ColorValue} to {T}. Different results... I can't really tell if it's better or worse. What do you think?

tmp

@timholy
Copy link
Member

timholy commented Sep 18, 2015

Hmm. It's not very clear, I agree. Suggests it's not a major bug, however (which is a bit of a relief), unless the bug is in the new colordiff function itself. If you run the old in the context of Color.jl and just compare the produced RGB values, I assume they are the same?

@tbreloff
Copy link
Member Author

They don't match exactly, but they're very close.

Color.jl:

julia> distinguishable_colors(10, RGB(0,0,0))
10-element Array{Color.RGB{Float64},1}:
 Color.RGB{Float64}(0.0,0.0,0.0)                               
 Color.RGB{Float64}(0.9986073236184781,1.0,0.3854174328603523) 
 Color.RGB{Float64}(1.0,0.6248223096436734,1.0)                
 Color.RGB{Float64}(0.0,0.8373117832059401,1.0)                
 Color.RGB{Float64}(0.8416678305286033,0.2660289846541403,0.0) 
 Color.RGB{Float64}(0.0,0.5034224573325012,0.16145544004112622)
 Color.RGB{Float64}(0.0,0.37128962559468526,0.8351670903389566)
 Color.RGB{Float64}(0.5776284927788988,0.0,0.4081931368120805) 
 Color.RGB{Float64}(1.0,0.7956789870901464,0.7082291085558009) 
 Color.RGB{Float64}(0.6561843152767537,0.5250735333870521,0.0)

Colors.jl:

julia> distinguishable_colors(10, RGB(0,0,0))
10-element Array{ColorTypes.RGB{FixedPointNumbers.UfixedBase{UInt8,8}},1}:
 RGB{U8}(0.0,0.0,0.0)    
 RGB{U8}(1.0,1.0,0.384)  
 RGB{U8}(1.0,0.624,1.0)  
 RGB{U8}(0.0,0.839,1.0)  
 RGB{U8}(0.843,0.267,0.0)
 RGB{U8}(0.0,0.494,0.0)  
 RGB{U8}(0.0,0.373,0.835)
 RGB{U8}(0.576,0.0,0.408)
 RGB{U8}(1.0,0.796,0.71) 
 RGB{U8}(0.659,0.525,0.0)

@tbreloff
Copy link
Member Author

So I think I may have a bug in my subplot code... the colors generated by distinguishable_colors are better than those subplots above show. However, I'm playing with an additional adjustment for adjusting lightness based on the background, which I think helps with those colors that are a little too dark:

# move closer to lighter/darker depending on background value
function adjustAway(val, bgval, vmin=0., vmax=100.)
  if bgval < 0.5 * (vmax+vmin)
    return 0.5 * (max(val, bgval) + vmax)
  else
    return 0.5 * (min(val, bgval) + vmin)
  end
end

function getBackgroundRGBColor(c, d::Dict)
  bgcolor = convertColor(d[:background_color])
  d[:background_color] = bgcolor
  palette = distinguishable_colors(20, bgcolor)[2:end]

  # try to adjust lightness away from background color
  bg_lab = Lab(bgcolor)
  palette = RGB{Float64}[begin
    lab = Lab(rgb)
    Lab(
        adjustAway(lab.l, bg_lab.l, 25, 75),
        lab.a,
        lab.b
      )
  end for rgb in palette]

  d[:color_palette] = palette
  bgcolor
end

The original version:

tmp

The adjusted version:

tmp

@tbreloff
Copy link
Member Author

For completeness... I found the bug. Subplots look good enough now. Thanks for the help.

tmp

@timholy
Copy link
Member

timholy commented Sep 19, 2015

Nice!

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

No branches or pull requests

5 participants