Basics
ColorScheme objects
When you start using ColorSchemes
, it loads a set of pre-defined ColorSchemes in a dictionary called colorschemes
.
A ColorScheme is a Julia object which contains:
- an ordered array of colors (see Colors.jl)
- a string defining a category
- a string containing descriptive notes
To access one of the built-in colorschemes, use its symbol:
ColorSchemes.leonardo
or
colorschemes[:leonardo]
The display depends on your working environment. If you’re using a notebook or IDE environment, the colors in the colorscheme should appear as a swatch in a cell or in a Plots window. Otherwise, you’ll see the colors listed as RGB values:
32-element Array{RGB{Float64},1}:
RGB{Float64}(0.0548203,0.016509,0.0193152)
RGB{Float64}(0.0750816,0.0341102,0.0397083)
RGB{Float64}(0.10885,0.0336675,0.0261204)
RGB{Float64}(0.100251,0.0534243,0.0497594)
...
RGB{Float64}(0.620187,0.522792,0.216707)
RGB{Float64}(0.692905,0.56631,0.185515)
RGB{Float64}(0.681411,0.58149,0.270391)
RGB{Float64}(0.85004,0.540122,0.136212)
RGB{Float64}(0.757552,0.633425,0.251451)
RGB{Float64}(0.816472,0.697015,0.322421)
RGB{Float64}(0.933027,0.665164,0.198652)
RGB{Float64}(0.972441,0.790701,0.285136)
You can access the array of colors as:
ColorSchemes.leonardo.colors
By default, the names of the built-in colorschemes aren’t imported. You can import the ones that you want:
julia> import ColorSchemes.leonardo
julia> leonardo
32-element Array{RGB{Float64},1}:
RGB{Float64}(0.0548203,0.016509,0.0193152)
RGB{Float64}(0.0750816,0.0341102,0.0397083)
RGB{Float64}(0.10885,0.0336675,0.0261204)
RGB{Float64}(0.100251,0.0534243,0.0497594)
...
RGB{Float64}(0.757552,0.633425,0.251451)
RGB{Float64}(0.816472,0.697015,0.322421)
RGB{Float64}(0.933027,0.665164,0.198652)
RGB{Float64}(0.972441,0.790701,0.285136)
You can reference a single color in a scheme:
leonardo[3]
-> RGB{Float64}(0.10884977211887092,0.033667530751245296,0.026120424375656533)
Or you can ‘sample’ the scheme at any point between 0 and 1 using get
or getindex
:
get(leonardo, 0.5)
-> RGB{Float64}(0.42637271063618504,0.28028983973265065,0.11258024276603132)
leonardo[0.5]
-> RGB{Float64}(0.42637271063618504,0.28028983973265065,0.11258024276603132)
With get
you can resample an existing colorscheme, by passing a range:
get(ColorSchemes.darkrainbow, range(0.0, 1.0, length=14))
-> RGB{Float64}[
RGB{Float64}(0.237736, 0.340215, 0.575113),
RGB{Float64}(0.249978, 0.343813, 0.5620657),
RGB{Float64}(0.259452, 0.386963, 0.464862),
RGB{Float64}(0.272746, 0.439684, 0.3499807),
...
RGB{Float64}(0.72987,0.239399,0.230961),
RGB{Float64}(0.72987,0.239399,0.230961)]
and you can make a new scheme from this:
ndr = ColorScheme(get(ColorSchemes.darkrainbow, range(0.0, 1.0, length=14)))
See below for more possibilities.
The colorschemes dictionary
The ColorSchemes module automatically provides a number of predefined schemes. All the colorschemes are stored in an exported dictionary, called colorschemes
.
colorschemes[:summer] |> show
ColorScheme(
ColorTypes.RGB{Float64}[
RGB{Float64}(0.0,0.5,0.4),
RGB{Float64}(0.01,0.505,0.4),
RGB{Float64}(0.02,0.51,0.4),
RGB{Float64}(0.03,0.515,0.4),
...
RGB{Float64}(1.0,1.0,0.4)],
"matplotlib",
"sampled color schemes, sequential linearly-increasing shades of green-yellow")
Finding colorschemes
Use the findcolorscheme function to search through the pre-defined colorschemes. The string you provide can occur in the colorscheme’s name, in the category, or (optionally) in the notes. It’s interpreted as a case-insensitive regular expression.
julia> findcolorscheme("ice")
colorschemes containing "ice"
seaborn_icefire_gradient
seaborn_icefire_gradient (notes) sequential, ice fire gradient...
ice
flag_is (notes) The flag of Iceland...
botticelli
botticelli (notes) palette from artist Sandro Bot...
...found 6 results for "ice"
The function returns a list of matching colorscheme names as symbols.
ColorSchemes.findcolorscheme
— Functionfindcolorscheme(str;
search_notes=true)
Find all colorschemes matching str
. str
is interpreted as a regular expression (case-insensitive).
This returns an array of symbols which are the names of matching schemes in the colorschemes
dictionary.
julia> findcolorscheme("ice")
colorschemes containing "ice"
seaborn_icefire_gradient
seaborn_icefire_gradient (notes) sequential, ice fire gradient...
ice
flag_is (notes) The flag of Iceland...
botticelli
botticelli (notes) palette from artist Sandro Bot...
...found 6 results for "ice"
To read the notes of a built-in colorscheme cscheme
:
colorschemes[:cscheme].notes
If you prefer, you can ‘roll your own’ search.
[k for (k, v) in ColorSchemes.colorschemes if occursin(r"colorbrew"i, v.category)]
265-element Array{Symbol,1}:
:BuPu_6
:Spectral_4
:RdYlGn_5
⋮
:BrBG_8
:Oranges_4
Make your own colorscheme
Using Colors.jl, you can use the ColorScheme
constructor to make a range of colors into a colorscheme.
Using Colors.jl's range()
:
cs1 = ColorScheme(range(colorant"red", colorant"green", length=5))
Using get()
:
cs1 = ColorScheme(get(ColorSchemes.darkrainbow, range(0.3, 0.7, length=10)))
Converting from a sequential palette:
cs1 = ColorScheme(reverse(Colors.sequential_palette(300, 100, logscale=true)))
From an array comprehension:
mygrays = ColorScheme([RGB{Float64}(i, i, i) for i in 0:0.1:1.0])
A logarithmic scheme:
ColorScheme(get(ColorSchemes.darkrainbow, 10 .^ range(-2, stop=0, length=50)))
Give it a category or some added notes if you want:
mygrays = ColorScheme([RGB{Float64}(i, i, i) for i in 0:0.1:1.0],
"my useful schemes", "just some dull grey shades")
although this scheme won’t be stored in the supplied colorschemes
dictionary.
Another example: start with a two-color scheme, then building a gradient from the first color to the other.
myscheme = ColorScheme([Colors.RGB(1.0, 0.0, 0.0), Colors.RGB(0.0, 1.0, 0.0)],
"custom", "twotone, red and green")
ColorScheme([get(myscheme, i) for i in 0.0:0.01:1.0])
Another way is to use the loadcolorscheme function used to build the colorschemes dictionary when the package is loaded:
using Colors, ColorSchemes
loadcolorscheme(:mygrays, [RGB{Float64}(i, i, i) for i in 0:0.1:1.0],
"useful schemes", "just some dull grey shades")
and that will be added (temporarily) to the built-in dictionary.
julia> findcolorscheme("dull")
colorschemes containing "dull"
mygrays (notes) just some dull grey shades...
...found 1 result for "dull"
If you want to make more advanced ColorSchemes, use linear-segment dictionaries or indexed lists, and use functions to generate color values, see the make_colorscheme()
function in the ColorSchemeTools.jl package.
For CVD (color-vision deficient or "color-blind") users
This package contains a number of colorschemes that are designed to be helpful for people with some deficiencies in their perception of color:
deuteranomaly (where green looks more red)
protanomaly (where red looks more green and less bright)
tritanomaly (difficult to tell the difference between blue and green, and between yellow and red)
tritanopia (difficult to tell the difference between blue and green, purple and red, and yellow and pink)
findcolorscheme("cvd")
colorschemes containing "cvd"
tol_light (category) cvd
tol_muted (category) cvd
tol_bright (category) cvd
okabe_ito (category) cvd
mk_8 (category) cvd
mk_12 (category) cvd
mk_15 (category) cvd
:tol_light
:tol_muted
:tol_bright
:okabe_ito
:mk_8
:mk_12
:mk_15
Also, it's possible to generate schemes using Colors.distinguishable_colors()
:
using Colors, ColorSchemes
ColorScheme(distinguishable_colors(10, transform=protanopic))
The resample()
function
Use resample()
to make a new colorscheme by resampling an existing one:
ColorSchemes.turbo
resample(ColorSchemes.turbo, 9)
You can pass a function to resample()
to control the alpha opacity of each color in the color scheme.
resample(ColorSchemes.turbo, 9, (alpha) -> 0.5)
This sets the alpha value of every color to 0.5.
resample(ColorSchemes.turbo, 30, (alpha) -> sin(alpha * π))
This example varies the alpha from 0 (at 0.0), 1 (at 0.5), and 0 (at 1.0).
More about color sampling
You can access the specific colors of a colorscheme by indexing (eg leonardo[2]
or leonardo[5:end]
). Or you can sample a ColorScheme at a point between 0.0 and 1.0 as if it were a continuous range of colors:
get(leonardo, 0.5)
returns
RGB{Float64}(0.42637271063618504,0.28028983973265065,0.11258024276603132)
The colors in the predefined ColorSchemes are usually sorted by LUV luminance, so this often makes sense.
You can use get()
with index data in arrays to return arrays of colors:
julia> get(leonardo, [0.0, 0.5, 1.0])
3-element Array{RGB{Float64},1} with eltype ColorTypes.RGB{Float64}:
RGB{Float64}(0.05482025926320272,0.016508952654741622,0.019315160361063788)
RGB{Float64}(0.42637271063618504,0.28028983973265065,0.11258024276603132)
RGB{Float64}(0.9724409077178674,0.7907008712807734,0.2851364857083522)
julia> simg = get(leonardo, rand(10, 16));
julia> using FileIO
julia> save("mosaic.png", simg)
Matplotlib compatibility
Most of the color schemes in Matplotlib are available. The following code example gives a general picture.
using ColorSchemes
# https://matplotlib.org/examples/color/colormaps_reference.html
matplotlibcmaps = Dict(
:perceptuallyuniformsequential => [
:viridis, :plasma, :inferno, :magma],
:sequential => [
:Greys_9, :Purples_9, :Blues_9, :Greens_9, :Oranges_9, :Reds_9,
:YlOrBr_9, :YlOrRd_9, :OrRd_9, :PuRd_9, :RdPu_9, :BuPu_9,
:GnBu_9, :PuBu_9, :YlGnBu_9, :PuBuGn_9, :BuGn_9, :YlGn_9],
:sequential2 => [
:binary, :gist_yarg, :gist_gray, :gray, :bone, :pink,
:spring, :summer, :autumn, :winter, :cool, :Wistia,
:hot, :afmhot, :gist_heat, :copper],
:diverging => [
:PiYG_11, :PRGn_11, :BrBG_11, :PuOr_11, :RdGy_11, :RdBu_11,
:RdYlBu_11, :RdYlGn_11, :Spectral_11, :coolwarm, :bwr, :seismic],
:cyclical => [
:twilight, :twilight_shifted, :hsv],
:qualitative => [
:Pastel1_9, :Pastel2_8, :Paired_11, :Accent_8,
:Dark2_8, :Set1_9, :Set2_8, :Set3_12,
:tab10, :tab20, :tab20b, :tab20c],
:miscellaneous => [
:flag, :prism, :ocean, :gist_earth, :terrain, :gist_stern,
:gnuplot, :gnuplot2, :CMRmap, :cubehelix, :brg, :hsv,
:gist_rainbow, :rainbow, :jet, :nipy_spectral, :gist_ncar]
)
for (k, v) in matplotlibcmaps
println("$(rpad(k, 12)) $(length(v))")
for cs in v
try
c = ColorSchemes.colorschemes[cs]
catch
println("\t$(rpad(cs, 12)) not currently in stock")
end
end
end
cyclical 3
twilight_shifted not currently in stock
sequential 18
qualitative 12
sequential2 16
gray not currently in stock
perceptuallyuniformsequential 4
diverging 12
miscellaneous 17