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 array of colors (eg
RGB(0.1, 0.3, 0.4)
) - a string defining a category
- a string that can contain descriptive notes
To access one of these 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 colorscheme names aren’t imported. To avoid using the prefixes, 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 value of 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)
Base.get
— Functionget(cscheme::ColorScheme, inData :: Array{Number, 2}, rangescale=:clamp)
get(cscheme::ColorScheme, inData :: Array{Number, 2}, rangescale=(minVal, maxVal))
Return an RGB array of colors generated by applying the colorscheme to the 2D input data.
If rangescale
is :clamp
the colorscheme is applied to values between 0.0-1.0, and values outside this range get clamped to the ends of the colorscheme.
If rangescale
is :extrema
, the colorscheme is applied to the range minimum(indata)..maximum(indata)
.
Else, if rangescale
is :centered
, the colorscheme is applied to the range -maximum(abs, indata)..maximum(abs, indata)
.
TODO: this function expects the colorscheme to consist of RGB [0.0-1.0] values. It should work with more colortypes.
Examples
img = get(colorschemes[:leonardo], rand(10,10)) # displays in Juno Plots window, but
save("testoutput.png", img) # you'll need FileIO or similar to do this
img2 = get(colorschemes[:leonardo], 10.0 * rand(10, 10), :extrema)
img3 = get(colorschemes[:leonardo], 10.0 * rand(10, 10), (1.0, 9.0))
# Also works with PerceptualColourMaps
using PerceptualColourMaps # warning, installs PyPlot, PyCall, LaTeXStrings
img4 = get(PerceptualColourMaps.cmap("R1"), rand(10,10))
get(cs::ColorScheme, g::Color{T,1} where T<:Union{Bool, AbstractFloat, FixedPoint})
Return the color in cs
that corresponds to the gray value g
.
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 quickly define a range of colors and use it to make a colorscheme:
using Colors, ColorSchemes
cs1 = ColorScheme(range(colorant"red", colorant"green", length=5))
using Colors, ColorSchemes
cs1 = ColorScheme(reverse(Colors.sequential_palette(300, 100, logscale=true)))
Or you can easily make your own by building an array:
using Colors, ColorSchemes
mygrays = ColorScheme([RGB{Float64}(i, i, i) for i in 0:0.1:1.0])
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 end up in the colorschemes
dictionary.
Another example, starting 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:
using Colors
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 list.
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))
Continuous 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
Alpha transparency
To convert a colorscheme to one with transparency, you could use a function like this:
function colorscheme_alpha(cscheme::ColorScheme, alpha::T = 0.5;
ncolors=12) where T<:Real
return ColorScheme([RGBA(get(cscheme, k), alpha) for k in range(0, 1, length=ncolors)])
end
colors = colorscheme_alpha(ColorSchemes.ice, ncolors=12)