Colors and Colormaps¶
This page covers practical usage: picking colors, mixing them, interpolating gradients, and using colormaps. For full visual catalogs, jump to the Colors, Palettes, or Colormaps catalogs under Design System.
What should I use?¶
If you need to… |
Use… |
Matplotlib surface |
|---|---|---|
color one mark, line, or area |
a named color token |
|
color separate series or categories |
a palette |
|
turn numeric values into colors |
a colormap |
|
create or adjust a color yourself |
the |
|
Tip
Most readers only need the first three rows. You can ignore the color-space math unless you want to create or adjust colors yourself.
Modeled relative CIE Y (relative_y) is calculated from nominal D65 sRGB; it
is not a measurement of a particular display, perceived brightness, or OKLab
L.
Four ideas¶
- Hue
Hue is the color family: red, green, and blue are different hues. In a line chart, changing hue can distinguish one series from another.
- Lightness
Lightness describes the light-to-dark direction. A sequential heatmap can use light colors for low values and dark colors for high values.
- Chroma
Chroma describes how colorful or muted a color is. In a scatter plot, a vivid highlight can have more chroma than the muted background points.
- Contrast
Contrast describes how strongly two neighboring colors stand apart. For example, a dark annotation on a white chart background has more contrast than a pale one.
- Palette
A palette is a finite list of colors. Use one to give the separate series in a bar chart distinct colors.
- Colormap
A colormap turns numeric values into colors. Use one to encode temperature across a heatmap or the values of points in a scatter plot.
- Sequential
Sequential means one ordered path from low to high. A population-density map can run from a light low end to a dark high end.
- Diverging
Diverging means two ordered arms meet at a meaningful center. A change chart can show decreases on one side of zero and increases on the other.
- Cyclic
Cyclic means the last color joins the first. It fits a phase or wind-direction chart where 360 degrees returns to 0 degrees.
- Qualitative
Qualitative, or categorical, means separate colors for labels with no numeric order, such as the species in a grouped scatter plot.
Named colors¶
dartwork-mpl ships its own curated palette — dc.* (“dartwork color”)
— and registers six third-party design systems alongside it for
cross-team consistency. Use any of them anywhere matplotlib accepts a
color.
Prefix |
Library |
Example |
|---|---|---|
|
dartwork Color (recommended) — 20 families × 10 perceptual steps, plus Octave as |
|
|
OpenColor |
|
|
Tailwind CSS |
|
|
Material Design |
|
|
Ant Design |
|
|
Chakra UI |
|
|
Primer (GitHub) |
|
Start with
dc.*for new figures — the palettes are tuned for publication-ready output. Reach for the third-party prefixes when you need to match an external brand or design system.The
dc.*namespace also holds 43 continuous colormaps and 13 qualitative colormaps (the two Octave cycles plus 11 curated sets) — see the Colormap catalog. Colormap names likedc.auroraonly work ascmap=arguments, not ascolor=strings; the named-colors above are the ones you pass tocolor=.
import matplotlib.pyplot as plt
import dartwork_mpl as dm
dm.style.use("presentation")
fig, ax = plt.subplots(figsize=dm.figsize("8cm", "wide"))
ax.plot([0, 1, 2], [1, 2, 1.5], marker="o", color="dc.green2", label="dc.green2")
ax.plot([0, 1, 2], [1.2, 1.6, 2.1], marker="s", color="dc.teal3", label="dc.teal3")
highlight = dm.mix_colors("dc.orange1", "white", alpha=0.45)
ax.fill_between([0, 1, 2], 0.9, 1.3, color=highlight, label="Mixed shade")
muted_line = dm.pseudo_alpha("dc.violet3", alpha=0.65, background="white")
ax.plot([0, 1, 2], [0.8, 1.1, 1.4], color=muted_line, label="Pseudo alpha")
ax.legend()
dm.simple_layout(fig)
Picking a dc.* swatch¶
The dc.* surface is 19 chromatic hue families plus gray (20 total), each with
10 steps. Index 0 is the light end and index 9 is the dark end. The ramps are
designed to give neighboring swatches clear separation while keeping a
reliable light-to-dark order.
Four separate jobs¶
- Construction
OKLab and OKLCH are used to construct and adjust colors. Construction uses ΔEOK to space neighboring steps. ΔEOK is a color-distance ruler: larger means more different.
- Modeled output ordering
Modeled
relative_yrecords nominal output ordering, with nominal black at 0 and nominal reference white at 1 under this software convention.- Independent validation
CIELAB, ΔE00, and color-vision deficiency (CVD) simulation are independent validation checks only. They do not construct colors or define modeled relative Y.
- Text contrast
Web Content Accessibility Guidelines (WCAG) contrast is a separate check for text against a known background. It does not certify an entire palette.
For the detailed construction, modeled-output, and validation evidence, see the Design rationale.
For unrelated categories use Octave via dm.set_colors() or dc.octave; for
related tones pick a family and sample the steps you need.
Palette |
Use it for |
|---|---|
|
Octave, for everyday unrelated categories |
|
Cool analytical series and ordered data |
|
Positive/negative states and status colors |
|
Warm emphasis, thresholds, and call-outs |
|
Editorial accents and qualitative groups |
|
Grid lines, baselines, secondary fills |
|
Diverging ± data — change, correlation |
|
Semantic highlight token |
→ The full token catalog lives on Colors; the series explorer lives on Palettes.
Coming from oc.*? A rough drop-in mapping:
If you were reaching for… |
Try… |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Palettes for separate series¶
To choose a series palette visually, use the
Palettes explorer. It previews Octave, curated
qualitative sets, family samples, black-and-white (B&W) and color-vision
deficiency (CVD) checks, and copyable
dm.set_colors(...) / dm.colors(..., n=...) calls.
Once you’ve picked a set, apply it in your own script:
import matplotlib as mpl
from cycler import cycler
dm.style.use("report") # base preset (font, line widths, spines, ...)
mpl.rcParams["axes.prop_cycle"] = cycler(color=[
"dc.teal3", "dc.teal1", "dc.teal5",
"dc.teal0", "dc.teal2", "dc.teal4",
])
Color class¶
For most plots, named color strings like "dc.teal3" are all you need. When
you need to programmatically adjust hue, saturation, or lightness — or
interpolate between colors in a perceptual color space — use the Color
class:
OKLab and OKLCH are two views of the same perceptual color model. OKLab is
convenient for color math; OKLCH exposes lightness L, chroma C, and hue
angle h for authoring.
import dartwork_mpl as dm
color = dm.oklch(0.7, 0.15, 150) # OKLCH (L, C, h°)
color.oklch.C *= 1.2 # boost chroma in-place
print(color.to_hex()) # '#...'
→ Full guide: Color class & manipulation — constructors, views, interpolation, and custom colormaps.
Color interpolation¶
import dartwork_mpl as dm
# Perceptual interpolation between colors (OKLCH by default)
palette = dm.cspace('#FF6B6B', '#4ECDC4', n=5, space='oklch')
for i, c in enumerate(palette):
ax.bar(i, 1, color=c.to_hex())
# Also supports 'oklab' and 'rgb' spaces
gradient = dm.cspace(dm.color('dc.red1'), dm.color('dc.teal3'), n=10)
Why OKLCH matters: Interpolating in RGB can produce muddy, desaturated midtones. OKLCH keeps hue and chroma explicit and often produces a smoother, more vivid path. It improves the interpolation geometry; it does not guarantee that every step looks exactly equal to every observer:
Exploring Available Colors¶
dartwork-mpl provides utilities to discover and explore available color families:
import dartwork_mpl as dm
# List available color-family records
families = dm.list_colors()
print(families[:2]) # [{'name': 'amber', 'kind': 'sequential', ...}, ...]
# Fetch a registered colormap or a designed discrete list
cmap = dm.colors("aurora")
cols = dm.colors("blue_red", n=5)
# Preview specific families
dm.show_colors(names=["blue", "blue_red"], n=5)
# Classify a colormap by type (takes a Colormap object)
import matplotlib as mpl
from dartwork_mpl.diagnostics import classify_cmap
cmap_type = classify_cmap(mpl.colormaps['dc.aurora'])
print(cmap_type) # 'Multi-Hue'
Colormaps¶
dartwork-mpl bundles custom colormaps prefixed with dc.. Their OKLab/OKLCH
construction is topology-specific: single-hue, continuous-gray, and multi-hue
sequential paths use ΔEOK arc-length resampling; diverging maps use symmetric
pointwise arms and integer resampling; hue uses equal hue angles; and the two
twilight cycles use closed-path ΔEOK resampling. Modeled relative Y is checked
against each map’s required direction or shape, followed by independent
finished-output diagnostics. They work like any matplotlib colormap:
import matplotlib.pyplot as plt
import dartwork_mpl as dm
from dartwork_mpl.diagnostics import classify_cmap
cmap = plt.colormaps["dc.aurora"]
print(cmap.name) # 'dc.aurora'
print(classify_cmap(cmap)) # 'Multi-Hue' (tells you the type)
Add _r to reverse any colormap (e.g., dc.aurora_r). Browse all available
colormaps on the Colormaps page.
Accessibility checklist¶
Important
Do not rely on hue alone for critical distinctions.
For ordered values, choose a map that still changes from light to dark.
For critical grayscale or print output, add labels, contours, markers, hatching, or line styles.
Web Content Accessibility Guidelines (WCAG) contrast applies to text against a known background; it does not certify an entire palette.
A color-vision deficiency (CVD) simulation is a useful model-based check, not a guarantee for every individual observer.
See also¶
Next → Layout and Typography — physical-width geometry, aspect tokens, and
simple_layoutDesign System → Colors / Palettes / Colormaps / Color class — the visual catalogs
Color sources:
asset/color/*.txt+ Tailwind/Material/Ant/Chakra/Primer/opencolor JSON