.. _chromophile:
The color maps
==============
We constructed the Chromophile color maps using the principles
described in the previous sections. These color maps are
lightness-uniform, hue-uniform, constant chroma, and constant
velocity. Hue uniformity and constant chroma are, as far as we
are aware, unique to our color maps. (:cite:p:`Kovesi` mentions
this possibility in the context of cyclic color maps, but his
design criteria ultimately lead him elsewhere.) The unique
treatment of chroma inspired the name "Chromophile."
The Chromophile color maps were designed in CAM16-UCS. When
CAM16-UCS is transformed to cylindrical coordinates, the radial
coordinate is denoted :math:`M'`, the angular coordinate is
:math:`h`, and the height coordinate is :math:`J'`. We call
:math:`M'` the uniformized colorfulness and :math:`J'` the
uniformized lightness. We write :math:`\Delta J'` for the
difference between the greatest and least values of :math:`J'` in
the color map.
Except for the isoluminant color maps, all the Chromophile color
maps contain pairs of colors with large lightness differences.
However, some of the color maps do not contain pairs with large
hue differences. Some, such as :code:`cp_seq_red_pink_cw1`, have
only modest hue differences, and a few, such as
:code:`cp_seq_green_green_cw`, have a nearly constant hue. These
are for visualizations with other constraints on the color map,
such as legibility against a colored background. In most
circumstances, we recommend color maps with large hue
differences.
The Chromophile color maps had one additional perceptual
constraint, legibility for people with color vision deficiency.
Illegible color maps are bad color maps, and there is no reason
to use, let alone design, a bad color map. Using the model of
:cite:p:`MOF` (as implemented in :cite:p:`colour-science`) we
evaluated the suitability of each color map for color vision
deficient viewers and, if necessary, adjusted it to make its
colors distinct for those viewers. Apart from a few instances
described later, we discarded color maps where this could not be
done. Viewers in whom one type of cone cell is unusual
(anomalous trichromacy) or absent or non-functional (dichromacy)
will perceive the Chromophile color maps differently from
non-anomalous trichromats, but they should not have difficulty
reading them. (Users who need a color map specifically optimized
for color vision deficient viewers should see :cite:p:`NAR`.)
Each of the Chromophile color maps is defined by a small number
of parameters. For instance, our sequential color maps are
determined by the initial and final lightnesses, the chroma, the
initial hue angle, and the change in hue angle. The small number
of parameters made it possible to automatically generate and
optimize color maps. With a few exceptions, the Chromophile
color maps were optimized by fixing the colorfulness and varying
the hue angles to maximize the difference in lightness between
their endpoints. Color map optimization was done using
:func:`scipy.optimize.minimize` with the :code:`method` parameter
set to :code:`trust-constr`. While optimization is never a
substitute for visual evaluation, it is much easier than
hand-tuning.
All the Chromophile color maps are designed for continuous data.
They are not meant for categorical features such as
distinguishing different lines on a shared line plot.
The gray color map
------------------
The standard sRGB grayscale color map is comprised of the colors
with sRGB coordinates (0, 0, 0), (1, 1, 1), …, (255, 255, 255).
This simplicity is deceptive, for the :math:`J'` values of this
color map are not linear in CAM16-UCS:
.. image:: /image/sRGB_gray_Jp.svg
:width: 90%
:alt: CAM16-UCS J' coordinate of the standard sRGB grayscale color map
:align: center
A secondary problem is that, as the lightness increases, the
color map steadily gains a slight cyan tint.
:code:`cp_seq_gray` fixes both these issues. The difference
between the sRGB grayscale (top) and :code:`cp_seq_gray`
(bottom) is small, but visible:
.. image:: /image/sRGB_gray.png
:width: 90%
:height: 3em
:alt: The standard sRGB grayscale color map
:align: center
.. raw:: html
.. image:: /image/cp_seq_gray.png
:width: 90%
:height: 3em
:alt: cp_seq_gray
:align: center
Sequential color maps
---------------------
Sequential color maps are used when the data consists of real
numbers. There are fifteen sequential Chromophile color maps
(excluding order-reversed variants and :code:`cp_seq_gray`).
They have systematic names of the form:
:samp:`cp_seq_{}_{}_{}{}`
The possible directions were :code:`cw` and :code:`ccw`
(referring to clockwise and counterclockwise directions in the
chromaticity coordinates of CAM16-UCS). Most color maps do not
have an optional number. For the ones that do, the number is
:code:`1` if the color map's hues are confined to a small
sector and :code:`2` if the hues span more than one but less
than two full circles.
All of the sequential color maps have 256 colors, :math:`M' =
20`, and :math:`\Delta J' \ge 80`. Because the sequential
Chromophile color maps have a steady increase in lightness, they
should be legible (though not optimal) for people with any type
of color vision deficiency, even full monochromacy. The
parameters of these color maps are:
.. list-table::
:header-rows: 1
:class: table-col-2-r table-col-3-r table-col-4-r table-col-5-r table-col-6-r table-col-7-r
* - Name
- :math:`J_0'`
- :math:`J_1'`
- :math:`\Delta J'`
- :math:`h_0`
- :math:`h_1`
- :math:`\Delta h`
* - :code:`cp_seq_blue_cyan_ccw`
- 7.38
- 94.90
- 87.52
- −77.15°
- 197.44°
- 274.59°
* - :code:`cp_seq_blue_cyan_cw`
- 7.38
- 94.90
- 87.52
- −77.15°
- −162.56°
- −85.41°
* - :code:`cp_seq_blue_pink_ccw1`
- 7.38
- 89.64
- 82.26
- −77.15°
- −32.01°
- 45.14°
* - :code:`cp_seq_blue_pink_ccw2`
- 7.38
- 89.57
- 82.18
- −77.15°
- −31.70°
- 405.45°
* - :code:`cp_seq_blue_yellow_ccw`
- 7.38
- 98.15
- 90.77
- −77.15°
- 111.96°
- 189.11°
* - :code:`cp_seq_blue_yellow_cw`
- 7.85
- 98.15
- 90.31
- −71.99°
- −248.04°
- −176.05°
* - :code:`cp_seq_green_cyan_ccw`
- 14.58
- 94.90
- 80.33
- 142.36°
- 197.44°
- 55.08°
* - :code:`cp_seq_green_green_cw`
- 14.58
- 95.71
- 81.13
- 142.36°
- 137.36°
- −5.00°
* - :code:`cp_seq_green_yellow_cw`
- 14.58
- 98.15
- 83.58
- 142.36°
- 111.96°
- −30.39°
* - :code:`cp_seq_red_cyan_ccw`
- 9.61
- 94.90
- 85.30
- 17.26°
- 197.44°
- 180.18°
* - :code:`cp_seq_red_cyan_cw`
- 8.70
- 94.90
- 86.21
- 27.25°
- −162.56°
- −189.81°
* - :code:`cp_seq_red_pink_cw1`
- 8.70
- 89.64
- 80.95
- 27.25°
- −32.01°
- −59.25°
* - :code:`cp_seq_red_pink_cw2`
- 8.70
- 89.24
- 80.54
- 27.25°
- −33.49°
- −420.73°
* - :code:`cp_seq_red_yellow_ccw`
- 8.70
- 98.15
- 89.46
- 27.25°
- 111.96°
- 84.72°
* - :code:`cp_seq_red_yellow_cw`
- 8.70
- 98.15
- 89.46
- 27.25°
- −248.04°
- −275.28°
Here, :math:`J_0'` and :math:`J_1'` are the uniformized
lightnesses of the initial and final colors, :math:`\Delta J'` is
their difference, :math:`h_0` and :math:`h_1` are the hue angles
of the initial and final colors, and :math:`\Delta h` is the
change in hue angle along the color map.
The sequential color maps were found using a systematic search of
directed arcs on a circle. The endpoints of each arc were used
as the chromaticity coordinates of the endpoints of a color map.
The initial lightness was set to :math:`J' = 20` and the final
lightness to :math:`J' = 80`. The color map was optimized to
maximize :math:`\Delta J'` under the constraint that the hue
angles of the endpoints were near their starting points.
Among color maps whose hues made one or less full winding around
the circle, there were 78 combinations of starting color, ending
color, and direction. However, these led to only thirteen
Chromophile color maps. The remaining color maps had too small a
value of :math:`\Delta J'` or were duplicates (exact or near) of
the others. In every case, when a color map's :math:`\Delta J'`
was too small, it was because the dark endpoint was not dark
enough, and ultimately, that was because sRGB does not contain
very dark browns and azures. There is little flexibility in the
Chromophile color maps; a color map that goes clockwise from
green to pink, for example, necessarily passes through brown. If
the initial lightness is low, then those browns are so dark that
they are not in sRGB, but increasing the initial lightness makes
:math:`\Delta J'` too small. This explains the small number of
color maps starting at green: Any color map starting at green
must avoid brown, so it cannot travel clockwise very far, and it
must avoid azure, so it cannot travel counterclockwise very far,
either. The only Chromophile color maps containing dark green
have similar starting and ending hues, and their darkest colors
are lighter than the darkest colors of the other Chromophile
color maps.
Multi-sequential color maps
---------------------------
Multi-sequential color maps are used for data consisting of a
real variable and a categorical variable. The categorical
variable is used to select a sequential color map, and the real
variable selects a color from that color map. Multi-sequential
color maps are not often needed in practice, but an example can
be seen in Figure 3h of :cite:p:`TGHZD`.
Each sequence in each of the multi-sequential Chromophile color
maps has 256 colors, so the full color map has between 512 and
1024 colors. Their names follow the pattern:
:samp:`cp_mseq_{}_{}{_}{_}`
Their parameters are:
.. list-table::
:header-rows: 1
:class: table-col-2-r table-col-3-r table-col-4-r table-col-5-r table-col-6-r table-col-7-r
* - Name
- :math:`J_0'`
- :math:`J_1'`
- :math:`\Delta J'`
- :math:`h_0`
- :math:`h_1`
- :math:`\Delta h`
* - :code:`cp_mseq_green_blue`
- 14.58
- 94.90
- 80.33
- 142.36°
- 142.36°
- 0.00°
* -
-
-
-
- −89.66°
- −162.56°
- −72.90°
* - :code:`cp_mseq_green_purple`
- 11.22
- 91.22
- 80.00
- 142.36°
- 142.36°
- 0.00°
* -
-
-
-
- −32.81°
- −32.81°
- 0.00°
* - :code:`cp_mseq_green_red`
- 11.22
- 91.22
- 80.00
- 142.36°
- 142.36°
- 0.00°
* -
-
-
-
- 25.00°
- −32.81°
- −57.81°
* - :code:`cp_mseq_orange_blue`
- 8.70
- 94.90
- 86.21
- 27.25°
- 102.83°
- 75.59°
* -
-
-
-
- −79.67°
- −162.56°
- −82.90°
* - :code:`cp_mseq_orange_teal`
- 14.58
- 94.90
- 80.33
- 36.67°
- 102.83°
- 66.16°
* -
-
-
-
- 142.36°
- 197.44°
- 55.08°
* - :code:`cp_mseq_purple_orange`
- 8.83
- 89.64
- 80.82
- −60.00°
- −32.01°
- 27.99°
* -
-
-
-
- 27.47°
- 86.82°
- 59.35°
* - :code:`cp_mseq_red_blue`
- 7.14
- 87.14
- 80.00
- 27.24°
- −14.85°
- −42.09°
* -
-
-
-
- −79.90°
- −120.00°
- −40.10°
* - :code:`cp_mseq_teal_purple`
- 11.22
- 91.22
- 80.00
- 142.36°
- 180.00°
- 37.64°
* -
-
-
-
- −32.81°
- −32.81°
- 0.00°
* - :code:`cp_mseq_orange_blue_purple`
- 8.88
- 89.64
- 80.76
- 27.57°
- 86.82°
- 59.24°
* -
-
-
-
- −80.01°
- −142.99°
- −62.98°
* -
-
-
-
- −59.22°
- −32.01°
- 27.21°
* - :code:`cp_mseq_orange_green_blue`
- 14.58
- 94.90
- 80.33
- 36.67°
- 102.83°
- 66.16°
* -
-
-
-
- 142.36°
- 142.36°
- 0.00°
* -
-
-
-
- −89.66°
- −162.56°
- −72.90°
* - :code:`cp_mseq_orange_green_blue_purple`
- 11.22
- 91.22
- 80.00
- 36.62°
- 88.11°
- 51.50°
* -
-
-
-
- 142.36°
- 142.36°
- 0.00°
* -
-
-
-
- −87.57°
- −143.19°
- −55.62°
* -
-
-
-
- −32.81°
- −32.81°
- 0.00°
To find multi-sequential color maps containing two sequences, we
performed a systematic search, similar to the one for sequential
color maps, of pairs of directed arcs on a circle. This search
used :math:`M' = 20`, and we kept only color maps that achieved
:math:`\Delta J' \ge 80`. There was one exception,
:code:`cp_mseq_red_blue`. The red and blue multisequential
color map that resulted from the search had colors that could not
be distinguished by some dichromats, and there seemed to be no
way to remove this ambiguity while meeting our other
requirements. Red and blue are such a popular pairing that we
kept this color map anyway. We re-optimized, this time
restricting the endpoints to ensure legibility for color vision
deficient viewers, requiring :math:`\Delta J'` to be at least
80, and aiming to make :math:`M'` as large as possible.
The final :math:`M'` was 18.15.
A similar search of triples of directed arcs found
:code:`cp_mseq_orange_blue_purple` and
:code:`cp_mseq_orange_green_blue`. Searching quadruples
resulted in no color maps that achieved :math:`M' = 20` and
:math:`\Delta J' \ge 80`.
:code:`cp_mseq_orange_green_blue_purple` was produced by
imposing the constraint :math:`\Delta J' \ge 80` and maximizing
:math:`M'`. The result was :math:`M' = 17.65`.
The multi-sequential Chromophile color maps with two sequences
should be legible for dichromats. Those with three or four
sequences should be legible for anomalous trichromats but are
probably not legible for dichromats. It is possible to design a
color map with three or four sequences of colors that all appear
distinct to a dichromat. Two of the sequences would appear very
colorful and the others would have the same colors but appear
more gray. However, it seems difficult, maybe impossible, to do
this simultaneously for all the different types of dichromats
while meeting the other criteria for Chromophile color maps.
Divergent color maps
--------------------
Divergent color maps, sometimes called bipolar color maps, are a
type of multi-sequential color map. They are used when the data
consists of real numbers, one of those numbers is the boundary
between two qualitatively different categories, and the
visualization should communicate distance from the boundary.
This situation often arises when plotting differences.
Divergent color maps are not a substitute for contour lines. If
the boundary value has no special meaning, then divergent color
maps are unnecessary and may even be deceptive.
Some divergent color maps can also be used as sequential color
maps (for example, :cite:p:`Moreland` was designed with that goal
in mind). The divergent Chromophile color maps were not intended
for this and should not be used for sequential data.
Each divergent Chromophile color map consists of two sequential
color maps of 256 colors each, for a total of 512 colors. There
are two types of divergent Chromophile color maps. One type has
a sharp transition at the boundary. These color maps are just
rearrangements of two-sequence multi-sequential color maps, so
they will not be discussed further. The other type makes a
smooth transition at the boundary. There are five divergent
Chromophile color maps of this type. Their names have the form:
:samp:`cp_div_{}_{}_{}`
The divergence type is "hill" or "valley" according to whether
the transition between the two categories happens at a light or a
dark color. The parameters for these color maps are:
.. list-table::
:header-rows: 1
:class: table-col-2-r table-col-3-r table-col-4-r table-col-5-r table-col-6-r table-col-7-r
* - Name
- :math:`J_0'`
- :math:`J_1'`
- :math:`\Delta J'`
- :math:`h_0`
- :math:`h_1`
- :math:`\Delta h`
* - :code:`cp_div_blue_orange_valley`
- 10.34
- 94.90
- 84.57
- 4.90°
- −162.56°
- −167.46°
* -
-
-
-
- 5.10°
- 102.83°
- 97.73°
* - :code:`cp_div_green_blue_hill`
- 14.79
- 94.79
- 80.00
- 142.62°
- 194.16°
- 51.55°
* -
-
-
-
- −90.00°
- −164.84°
- −74.84°
* - :code:`cp_div_green_cyan_valley`
- 14.61
- 94.90
- 80.29
- 142.30°
- 132.30°
- −10.00°
* -
-
-
-
- 142.40°
- 197.44°
- 55.04°
* - :code:`cp_div_orange_blue_hill`
- 9.18
- 94.47
- 85.29
- 22.34°
- 180.00°
- 157.66°
* -
-
-
-
- −80.55°
- −177.00°
- −96.45°
* - :code:`cp_div_pink_orange_valley`
- 9.91
- 89.91
- 80.00
- 5.00°
- −32.13°
- −37.13°
* -
-
-
-
- 5.10°
- 87.03°
- 81.93°
Hill and valley color maps are equally usable but are good for
different purposes. Imagine, for example, that you are comparing
a model to experimental data, and the plot shows the amount and
direction of residual error. If the residual is displayed
against a dark background, then light colors will draw a viewer's
attention. A hill map will focus attention on where the model is
correct: "Look at how good my model is!" A valley map will focus
attention on where the model is incorrect: "Look at how bad their
model is!"
There are fewer divergent Chromophile color maps than sequential
or even multisequential color maps because it was difficult to
make these color maps legible for viewers with color vision
deficiency. We chose the central hue so that viewers with red or
green cone cell abnormalities see a color transition there.
These color maps should also be legible for viewers with blue
cone cell abnormalities.
The color map :code:`cp_div_pink_orange_valley` is very slightly
lower quality than the others. After the central hue was
adjusted to make the color map legible for viewers with red and
green cone cell deficiencies, the color map had :math:`\Delta J'
= 79.31`. This was so close to :math:`\Delta J' = 80`, and there
were so few divergent color maps, that we compromised. We
required :math:`\Delta J' \ge 80` and maximized :math:`M'`,
getting a color map with :math:`M' = 19.61`.
We made but rejected four other divergent color maps. Three
would have been valley color maps:
:code:`cp_div_blue_purple_valley`,
:code:`cp_div_green_purple_valley`, and
:code:`cp_div_orange_green_valley`. One would have been a
hill color map, :code:`cp_div_orange_green_hill`. All of
these were acceptable for non-anomalous trichromats and viewers
with blue cone cell abnormalities. However, there was no way to
make them legible for viewers with red or green cone cell
abnormalities.
Isoluminant color maps
----------------------
Isoluminant color maps may be appropriate when used to display
secondary or tertiary properties of the data and when a color's
lightness is dictated by other considerations. For example, in
three-dimensional renderings, isoluminant color maps are the only
color maps that do not interact with the scene's lighting. In
principle, they should be ideal for such renderings. However, as
explained earlier in :ref:`uniformity`, they make details so
difficult to discern that resulting visualizations are often
worthless (this was noted by :cite:p:`Moreland`). They should be
used cautiously if at all.
For those cases where isoluminant color maps are appropriate,
there are nine isoluminant Chromophile color maps. They come in
three families of three color maps each. One of these families
consists of cyclic color maps and will be discussed later. The
others are sequential color maps whose names have the form:
:samp:`cp_isolum_{}_{}_{