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 Vector{RGB{FixedPointNumbers.N0f8}}:
 RGB(1.0, 0.0, 0.0)
 RGB(0.929, 0.035, 0.0)
 RGB(0.859, 0.071, 0.0)
 RGB(0.784, 0.106, 0.0)
 RGB(0.714, 0.145, 0.0)
 RGB(0.643, 0.18, 0.0)
 RGB(0.573, 0.216, 0.0)
 RGB(0.502, 0.251, 0.0)
 RGB(0.427, 0.286, 0.0)
 RGB(0.357, 0.322, 0.0)
 RGB(0.286, 0.357, 0.0)
 RGB(0.216, 0.396, 0.0)
 RGB(0.141, 0.431, 0.0)
 RGB(0.071, 0.467, 0.0)
 RGB(0.0, 0.502, 0.0)

If you use Julia through VSCode 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 to stop, inclusive, returning an Array of colors.

Julia 1.1

stop as a positional argument requires at least Julia 1.1.

source

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.8, colorant"red", colorant"green")
RGB{N0f8}(0.8, 0.102, 0.0)

You can also get the weighted mean of three or more colors by passing the collections of weights and colors. The following is an example of bilinear interpolation.

[weighted_color_mean([(1-s)*(1-t), s*(1-t), (1-s)*t, s*t], # collection of weights
                     Colors.JULIA_LOGO_COLORS)             # collection of colors
                            for s = 0:0.2:1, t = 0:0.05:1]
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.

source
weighted_color_mean(weights, colors)

Returns the weighted mean of the given collection colors with weights. This is semantically equivalent to the calculation of sum(weights .* colors).

Examples

julia> rgbs = (RGB(1, 0, 0), RGB(0, 1, 0), RGB(0, 0, 1));

julia> weighted_color_mean([0.2, 0.2, 0.6], rgbs)
RGB{N0f8}(0.2, 0.2, 0.6)

julia> weighted_color_mean(0.5:-0.25:0.0, RGB{Float64}.(rgbs))
RGB{Float64}(0.5, 0.25, 0.0)
Colors v0.13

wighted_color_mean with collection or iterator inputs requires Colors v0.13 or later.

Note

In a cylindrical color space such as HSV, a weighted mean of more than three colors is generally not meaningful.

source

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, <keyword arguments>])

The cname specifies the name of colormap. The currently supported names are:

Sequential

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

Diverging

  • "RdBu" (from red to blue)

The optional arguments of colormap() are:

  • the number of colors N
  • position of the middle point mid for diverging colormaps
  • 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.

Colors.colormapFunction
colormap(cname, N=100; logscale=false, <keyword arguments>)

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

Sequential colormaps cname choices are:

  • "Blues"
  • "Grays"
  • "Greens"
  • "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.

source

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
C* L* 0.1 0.5 0.9 c - contrast [0,1] C* L* 0.1 0.5 0.9 s - saturation [0,1] C* L* 0.1 0.5 0.9 b - brightness [0,1] 0.0 0.2 0.4 0.6 0.8 1.0 w - strength of wcolor [0,1] wcolor 0.0 0.2 0.4 0.6 0.8 1.0 d - strength of dcolor [0,1] dcolor

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

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, h2 - the main hue of the first/latter part [0,360]

and the optional arguments are:

  • N - number of colors
  • mid - the position of the midpoint (0,1)
  • c, s, b - contrast, saturation, brightness [0,1]
  • w - cold/warm parameter, i.e. the strength of the middle color [0,1]
  • d1, d2 - depth of the ending color in the first/latter part [0,1]
  • wcolor - starting color i.e. the middle color
  • dcolor1, dcolor2 - ending color of the first/latter part (depth)
  • logscale - true/false for toggling logspacing

For examples:

diverging_palette(0, 200, 32)
diverging_palette(0, 200, 32, mid=0.3)
diverging_palette(0, 200, 32, mid=0.3, logscale=true)
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
source
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
  • mid - the position of the midpoint (0,1)
  • h1 - the main hue of the first part [0,360]
  • h2 - the main hue of the latter part [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 first part [0,1]
  • d2 - depth of the ending color in the latter part [0,1]
  • wcolor - starting color, i.e. the middle color (warmness)
  • dcolor1 - ending color of the first part (depth)
  • dcolor2 - ending color of the latter part (depth)
  • logscale - true/false for toggling logspacing
source

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(n::Integer, seed::AbstractVector{<:Color})

By default, distinguishable_colors chooses maximally distinguishable colors from the outer product of lightness, chroma, and hue values specified by lchoices, cchoices, and hchoices. The set of colors that distinguishable_colors chooses from can be specified by passing different choices as keyword arguments.

distinguishable_colors(n::Integer, seed::AbstractVector{<:Color};
    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.

source