Color Range: pick color in range base on values in a vector

Note that linear interpolation will yield a colormap that is not perceptually uniform, so it will tend to distort data (see e.g. this nice video on the design of matplotlib’s color schemes). You can use the PerceptualColormaps.jl package to correct this, for example:

using Colors, ColorSchemes, PerceptualColourMaps

cs = ColorScheme([colorant"yellow", colorant"red"])
origcolors = get(cs, 0:0.01:1) # linear interpolation, not perceptually uniform

# generate corrected colormap:
rgbdata = equalisecolourmap("RGB", RGBA{Float64}.(origcolors), "CIEDE2000", [1,0,0])
newcolors = [RGB(rgb...) for rgb in eachrow(rgb)]

Compare the original linear colormap origcolors (top) with the corrected colormap newcolors (bottom):



You can see that the original linearly interpolated scheme washes out some of the visual contrast, especially on the red (right) side of the scale.

Then you can create a ColorScheme object and do interpolation on it:

newcs = ColorScheme(newcolors)

wealth = [1, 12, 45, 2, 129, 10]
colors = get(newcs, wealth, :extrema)


Note that there is no need to do broadcasting: you can do get(newcs, somearray, :extrema) rather than get.(Ref(newcs), normalized_somearray), because the ColorSchemes.jl package implements a vectorized get method, and by passing :extrema as the third argument it will automatically normalize the data (and you can also pass a different normalization).

2 Likes