Colormaps and Colorscales

Color interpolation

Generating a range of colors

The range() function has a method that accepts colors:

    Base.range(start::T; stop::T, length=100) where T<:Colorant

This generates N (=length) colors in a linearly interpolated ramp from start to stop, inclusive, returning an Array of colors.

julia> using Colors

julia> c1 = colorant"red"
RGB{N0f8}(1.0,0.0,0.0)

julia> c2 = colorant"green"
RGB{N0f8}(0.0,0.502,0.0)

julia> range(c1, stop=c2, length=15)
15-element Array{RGB{N0f8},1} with eltype RGB{FixedPointNumbers.N0f8}:
 RGB{N0f8}(1.0,0.0,0.0)
 RGB{N0f8}(0.929,0.035,0.0)
 RGB{N0f8}(0.859,0.071,0.0)
 RGB{N0f8}(0.784,0.11,0.0)
 RGB{N0f8}(0.714,0.145,0.0)
 RGB{N0f8}(0.643,0.18,0.0)
 RGB{N0f8}(0.573,0.216,0.0)
 RGB{N0f8}(0.502,0.251,0.0)
 RGB{N0f8}(0.427,0.286,0.0)
 RGB{N0f8}(0.357,0.322,0.0)
 RGB{N0f8}(0.286,0.357,0.0)
 RGB{N0f8}(0.216,0.392,0.0)
 RGB{N0f8}(0.141,0.431,0.0)
 RGB{N0f8}(0.071,0.467,0.0)
 RGB{N0f8}(0.0,0.502,0.0)

If you use Julia through Juno or IJulia, you can get the following color swatches.

range(colorant"red", stop=colorant"green", length=15)

The intermediate colors depend on their colorspace. For example:

range(HSL(colorant"red"), stop=HSL(colorant"green"), length=15)

The range and weighted_color_mean described below support colors with hues which are out of the range [0, 360]. The hues of generated colors are normalized into [0, 360].

range(HSV(0,1,1), stop=HSV(-360,1,1), length=90) # inverse rotation
range(LCHab(70,70,0), stop=LCHab(70,70,720), length=90) # multiple rotations

While sometimes useful in particular circumstances, typically it is recommended that the hue be within [0, 360]. See normalize_hue.

Base.rangeFunction
range(start::T; stop::T, length=100) where T<:Colorant
range(start::T, stop::T; length=100) where T<:Colorant

Generates N (=length) >2 colors in a linearly interpolated ramp from start tostop, inclusive, returning an Array of colors.

Julia 1.1

stop as a positional argument requires at least Julia 1.1.

Weighted color means

The weighted_color_mean() function returns a color that is the weighted mean of c1 and c2, where c1 has a weight 0 ≤ w1 ≤ 1.

For example:

julia> weighted_color_mean(0.5, colorant"red", colorant"green")
RGB{N0f8}(0.502,0.251,0.0)
Colors.weighted_color_meanFunction
weighted_color_mean(w1, c1, c2)

Returns the color w1*c1 + (1-w1)*c2 that is the weighted mean of c1 and c2, where c1 has a weight 0 ≤ w1 ≤ 1.

Colormaps

This package provides some pre-defined colormaps (described below). There are also several other packages which provide colormaps:

Predefined sequential and diverging colormaps

The colormap() function returns a predefined sequential or diverging colormap computed using the algorithm by Wijffelaars, M., et al. (2008).

colormap(cname::String [, N::Int=100; mid=0.5, logscale=false, kvs...])

The optional arguments are:

  • the number of colors N
  • position of the middle point mid
  • the use of logarithmic scaling with the logscale keyword

Colormaps computed by this algorithm are guaranteed to have an increasing perceived depth or saturation making them ideal for data visualization. This also means that they are (in most cases) color-blind friendly and suitable for black-and-white printing.

The currently supported colormap names are:

Sequential

  • "Blues"
  • "Greens"
  • "Grays"
  • "Oranges"
  • "Purples"
  • "Reds"

Diverging

  • "RdBu" (from red to blue)

Colors.colormapFunction
colormap(cname, N=100; mid=0.5, logscale=false, kvs...])

Returns a predefined sequential or diverging colormap computed using the algorithm by Wijffelaars, M., et al. (2008).

Sequential colormaps cname choices are:

  • Blues
  • Greens
  • Grays
  • Oranges
  • Purples,
  • Reds

Diverging colormap choices are RdBu.

Optionally, you can specify the number of colors N (default 100).

Extra control is provided by keyword arguments.

  • mid sets the position of the midpoint for diverging colormaps.
  • logscale=true uses logarithmically-spaced steps in the colormap.

You can also use keyword argument names that match the argument names in sequential_palette or diverging_palette.

Sequential and diverging color palettes

You can create your own color palettes by using sequential_palette():

sequential_palette(h, [N::Int=100; c=0.88, s=0.6, b=0.75, w=0.15, d=0.0, wcolor=RGB(1,1,0), dcolor=RGB(0,0,1), logscale=false])

which creates a sequential map for a hue h (defined in LCHuv space).

Other possible parameters that you can fine tune are:

  • N - number of colors
  • c - the overall lightness contrast [0,1]
  • s - saturation [0,1]
  • b - brightness [0,1]
  • w - cold/warm parameter, i.e. the strength of the starting color [0,1]
  • d - depth of the ending color [0,1]
  • wcolor - starting color (usually defined to be yellow)
  • dcolor - ending color (depth)
  • logscale - true/false for toggling logspacing

Two sequential maps can also be combined into a diverging colormap by using:

diverging_palette(h1, h2 [, N::Int=100; mid=0.5,c=0.88, s=0.6, b=0.75, w=0.15, d1=0.0, d2=0.0, wcolor=RGB(1,1,0), dcolor1=RGB(1,0,0), dcolor2=RGB(0,0,1), logscale=false])

where the arguments are:

  • h1 - the main hue of the left side [0,360]
  • h2 - the main hue of the right side [0,360]

and the optional arguments are:

  • N - number of colors
  • c - the overall lightness contrast [0,1]
  • s - saturation [0,1]
  • b - brightness [0,1]
  • w - cold/warm parameter, i.e. the strength of the middle color [0,1]
  • d1 - depth of the end color in the left side [0,1]
  • d2 - depth of the end color in the right side [0,1]
  • wcolor - starting color i.e. the middle color (warmness, usually defined to be yellow)
  • dcolor1 - end color of the left side (depth)
  • dcolor2 - end color of the right side (depth)
  • logscale - true/false for toggling logspacing
Colors.sequential_paletteFunction
sequential_palette(h, N::Int=100; <keyword arguments>)

Implements the color palette creation technique by Wijffelaars, M., et al. (2008).

Colormaps are formed using Bézier curves in LCHuv colorspace with some constant hue. In addition, start and end points can be given that are then blended to the original hue smoothly.

Arguments

  • N - number of colors
  • h - the main hue [0,360]
  • c - the overall lightness contrast [0,1]
  • s - saturation [0,1]
  • b - brightness [0,1]
  • w - cold/warm parameter, i.e. the strength of the starting color [0,1]
  • d - depth of the ending color [0,1]
  • wcolor - starting color (warmness)
  • dcolor - ending color (depth)
  • logscale - true/false for toggling logspacing
Colors.diverging_paletteFunction
diverging_palette(h1, h2, N::Int=100; <keyword arguments>)

Create diverging palettes by combining 2 sequential palettes

Arguments

  • N - number of colors
  • h1 - the main hue of the left side [0,360]
  • h2 - the main hue of the right side [0,360]
  • c - the overall lightness contrast [0,1]
  • s - saturation [0,1]
  • b - brightness [0,1]
  • w - cold/warm parameter, i.e. the strength of the starting color [0,1]
  • d1 - depth of the ending color in the left side [0,1]
  • d2 - depth of the ending color in the right side [0,1]
  • wcolor - starting color (warmness)
  • dcolor1 - ending color of the left side (depth)
  • dcolor2 - ending color of the right side (depth)
  • logscale - true/false for toggling logspacing

Generating distinguishable colors

distinguishable_colors() generates n maximally distinguishable colors in LCHab space. A seed color or array of seed colors can be provided, and the remaining colors will be chosen to be maximally distinguishable from the seed colors and each other.

distinguishable_colors(n::Integer, seed::Color)
distinguishable_colors{T<:Color}(n::Integer,seed::AbstractVector{T})

By default, distinguishable_colors chooses maximally distinguishable colors from the outer product of lightness, chroma, and hue values specified by lchoices = range(0, stop=100, length=15), cchoices = range(0, stop=100, length=15), and hchoices = range(0, stop=342, length=20). The set of colors that distinguishable_colors chooses from can be specified by passing different choices as keyword arguments.

distinguishable_colors{T<:Color}(n::Integer, seed::AbstractVector{T};
    dropseed = false,
    transform::Function = identity,
    lchoices::AbstractVector = range(0, stop=100, length=15),
    cchoices::AbstractVector = range(0, stop=100, length=15),
    hchoices::AbstractVector = range(0, stop=342, length=20)
)

Distinguishability is maximized with respect to the CIEDE2000 color difference formula (see colordiff in Color Differences). If a transform function is specified, color difference is instead maximized between colors a and b according to colordiff(transform(a), transform(b)).

Color arrays generated by distinguishable_colors are particularly useful for improving the readability of multiple trace plots. Here’s an example using PyPlot:

using PyPlot, Colors
vars = 1:10
cols = distinguishable_colors(length(vars), [RGB(1,1,1), RGB(0,0,0)], dropseed=true)
pcols = map(col -> (red(col), green(col), blue(col)), cols)
xs = 0:12
for i in vars
    plot(xs, map(x -> rand() + 0.1x - 0.5i, xs), c = pcols[i])
end
legend(vars, loc="upper right", bbox_to_anchor=[1.1, 1.])

pyplot seed ex

To ensure that the generated colors stand out against the default white background and black texts, white and black ([RGB(1,1,1), RGB(0,0,0)]) were used as seed colors to distinguishable_colors(), then dropped from the resulting array with dropseed=true.

The distinguishable_colors returns a vector of length n regardless of the dropseed option. If dropseed is true, the leading seed colors will be dropped, and the succeeding values ​​of length(seed) will be appended to the end.

permutedims(hcat(
    distinguishable_colors(10, [RGB(1,1,1), RGB(0,0,0)], dropseed=false),
    distinguishable_colors(10, [RGB(1,1,1), RGB(0,0,0)], dropseed=true),
    distinguishable_colors(12, [RGB(1,1,1), RGB(0,0,0)])[3:end] # manually drop the seed colors
))
Colors v0.10

dropseed requires at least Colors v0.10. If you use an older version, drop the seed manually.

Colors.distinguishable_colorsFunction
colors = distinguishable_colors(n, seed=RGB{N0f8}[];
                                dropseed=false,
                                transform=identity,
                                lchoices=range(0, stop=100, length=15),
                                cchoices=range(0, stop=100, length=15),
                                hchoices=range(0, stop=342, length=20))

Generate n maximally distinguishable colors.

This uses a greedy brute-force approach to choose n colors that are maximally distinguishable. Given seed color(s), and a set of possible hue, chroma, and lightness values (in LCHab space), it repeatedly chooses the next color as the one that maximizes the minimum pairwise distance to any of the colors already in the palette.

Arguments

  • n: Number of colors to generate.
  • seed: Initial color(s) included in the palette.

Keyword arguments

  • dropseed: if true, the seed values will be dropped. This provides an easy mechanism to ensure that the chosen colors are distinguishable from the seed value(s). When true, n does not include the seed color(s).
  • transform: Transform applied to colors before measuring distance. Default is identity; other choices include deuteranopic to simulate color-blindness.
  • lchoices: Possible lightness values
  • cchoices: Possible chroma values
  • hchoices: Possible hue values

Returns a Vector of colors of length n, of the type specified in seed.