Color Utilities¶
Importing dartwork_mpl registers the named color libraries that users reach
for in plotting code: dartwork Color (dc.), OpenColor (oc.), Tailwind
(tw.), Material Design (md.), Ant Design (ad.), Chakra UI
(cu.), and Primer (pr.). Use those strings anywhere matplotlib accepts
a color. In addition to the named palette, a Color class provides
perceptually uniform color manipulation across OKLab, OKLCH, RGB, and hex
color spaces.
Example¶
import matplotlib.pyplot as plt
import dartwork_mpl as dm
# Named colors
plt.plot(x, y, color="dc.teal2", label="Series A")
lighter = dm.mix_colors("dc.teal2", "white", alpha=0.35)
muted_line = dm.pseudo_alpha("dc.teal3", alpha=0.6)
# Color class — perceptual manipulation
color = dm.oklch(0.7, 0.15, 150)
color.oklch.C *= 1.2 # boost chroma
print(color.to_hex()) # '#...'
# Interpolation
palette = dm.cspace('#FF6B6B', '#4ECDC4', n=5, space='oklch')
for i, c in enumerate(palette):
ax.bar(i, 1, color=c.to_hex())
cspace('#FF6B6B', '#4ECDC4', n=8, space='oklch') interpolates perceptually
through OKLCH — hover a step for its hex:
Named colours, mix_colors, and pseudo_alpha compose
the same way — see the snippet above.
API¶
Color Manipulation¶
Color management and conversion utilities for Matplotlib.
Provides facilities for loading, registering, and converting colors across OKLab, OKLCH, RGB, and Hex color spaces.
- class dartwork_mpl._colors.Color(value: Color | str)[source]¶
Bases:
objectColor in OKLab/OKLCH/RGB/Hex color spaces.
A wrapper over a single canonical store (OKLab coordinates) with per-space property views (
color.oklab/color.oklch/color.rgb). The constructor takes a string (or pass-throughColor) — bare numerics are rejected because three floats give no way to tell OKLab apart from OKLCH or RGB. For already-typed numeric input, usefrom_oklab()/from_oklch()/from_rgb()/from_hex()/from_name()(or the top-level wrappersoklab()/oklch()/rgb()/hex()).Equality and hashing are by value — two colors with the same OKLab coordinates compare equal (
__eq__()) and hash equal (__hash__()).Note
Unlike
Length,Coloris currently mutable: theoklab/oklch/rgbviews write back to the underlying store in place (hencecopy()). Because it is both mutable and value-hashable, do not mutate aColorafter using it as adict/setkey. A future release will makeColorimmutable (view setters returning a new instance); see issue #233.- Parameters:
value (Color or str) – Either another
Color(returned as a fresh copy with the same OKLab coordinates) or a string parseable byColor.parse()— hex ("#ff0000"), functional ("rgb(1, 0, 0)"/"oklch(0.7, 0.15, 30)"/"oklab(...)"), or a palette/matplotlib color name ("oc.red5","red").
Examples
>>> import dartwork_mpl as dm >>> dm.Color("#ff0000") >>> dm.Color("oklch(0.7, 0.15, 30)") >>> dm.Color("oc.red5") >>> dm.Color(dm.oklab(0.7, 0.1, 0.2)) # pass-through copy
- copy() Color[source]¶
Create a copy of the Color object.
- Returns:
A new Color instance with the same OKLab coordinates.
- Return type:
Examples
>>> import dartwork_mpl as dm >>> color = dm.oklab(0.7, 0.1, 0.2) >>> new_color = color.copy() >>> >>> # Modify the copy without affecting the original >>> new_color.oklab.L += 0.1 >>> print(color.oklab.L) # 0.7 (unchanged) >>> print(new_color.oklab.L) # 0.8 (modified)
- classmethod from_hex(hex_str: str) Color[source]¶
Create a Color from hex color string.
- Parameters:
hex_str (str) – Hex color string (#RGB or #RRGGBB).
- Returns:
Color instance.
- Return type:
- classmethod from_name(name: str) Color[source]¶
Create a Color from matplotlib color name.
Supports all matplotlib color names including: - Basic colors: ‘red’, ‘blue’, ‘green’, etc. - Named colors: ‘aliceblue’, ‘antiquewhite’, etc. - Custom dartwork-mpl colors: ‘oc.red5’, ‘tw.blue500’, etc.
- Parameters:
name (str) – Matplotlib color name (e.g., ‘red’, ‘oc.blue5’, ‘tw.blue500’).
- Returns:
Color instance.
- Return type:
- Raises:
ValueError – If the color name is not recognized by matplotlib.
- classmethod from_oklab(L: float, a: float, b: float) Color[source]¶
Create a Color from OKLab coordinates.
- Parameters:
L (float) – OKLab coordinates (L typically in [0, 1]).
a (float) – OKLab coordinates (L typically in [0, 1]).
b (float) – OKLab coordinates (L typically in [0, 1]).
- Returns:
Color instance.
- Return type:
- classmethod from_oklch(L: float, C: float, h: float) Color[source]¶
Create a Color from OKLCH coordinates.
- Parameters:
L (float) – Lightness and Chroma (L typically in [0, 1], C >= 0).
C (float) – Lightness and Chroma (L typically in [0, 1], C >= 0).
h (float) – Hue in degrees [0, 360).
- Returns:
Color instance.
- Return type:
- classmethod from_rgb(r: float, g: float, b: float) Color[source]¶
Create a Color from RGB values.
Automatically detects if values are in [0, 1] or [0, 255] range. If all values are <= 1.0, treats as [0, 1]. Otherwise, treats as [0, 255]. In 0-255 mode the exact values
0and1are read as byte values (1→1/255, nearly black), since they are legitimate byte intensities — e.g.from_rgb(255, 0, 1); fractional values between 0 and 1 mixed into 0-255 mode are rejected as ambiguous instead.- Parameters:
r (float) – RGB values (auto-detected range).
g (float) – RGB values (auto-detected range).
b (float) – RGB values (auto-detected range).
- Returns:
Color instance.
- Return type:
- in_gamut(tol: float = 1e-06) bool[source]¶
Whether this color is representable inside the sRGB gamut.
Returns
Truewhen every linear-sRGB channel falls within[0, 1](withintol), i.e.to_rgb()returns the color directly. ReturnsFalsefor out-of-gamut colors, whichto_rgb()gamut-maps by reducing chroma while holding lightness and hue (so the rendered color stays close in L/h).- Parameters:
tol (float, optional) – Numerical tolerance on the
[0, 1]bounds, to absorb floating-point error at the gamut boundary. Default1e-6.- Return type:
bool
Examples
>>> import dartwork_mpl as dm >>> dm.Color.from_oklch(0.7, 0.05, 30).in_gamut() True >>> dm.Color.from_oklch(0.7, 0.40, 30).in_gamut() False
- property oklab: OklabView¶
Get OKLab view of the color.
- Returns:
View object for OKLab color space access.
- Return type:
Examples
>>> import dartwork_mpl as dm >>> color = dm.oklab(0.7, 0.1, 0.2) >>> >>> # Attribute access >>> L = color.oklab.L >>> a = color.oklab.a >>> >>> # Unpacking >>> L, a, b = color.oklab >>> >>> # Writing >>> color.oklab.L += 0.1
- property oklch: OklchView¶
Get OKLCH view of the color.
- Returns:
View object for OKLCH color space access.
- Return type:
Examples
>>> import dartwork_mpl as dm >>> color = dm.oklch(0.7, 0.2, 120) >>> >>> # Attribute access >>> L = color.oklch.L >>> C = color.oklch.C >>> h = color.oklch.h >>> >>> # Unpacking >>> L, C, h = color.oklch >>> >>> # Writing >>> color.oklch.C *= 1.2
- classmethod parse(value: str) Color[source]¶
Parse a string in any supported form into a
Color.Routes by the leading character / token of
value:"#rgb"/"#rrggbb"→from_hex()."rgb(r, g, b)"(auto 0-1 / 0-255 detection),"oklch(L, C, h)"(h in degrees),"oklab(L, a, b)"→ corresponding factory. Function name is case-insensitive; arguments are comma-separated and tolerant of internal whitespace.Anything else falls through to
from_name()(matplotlib named colors,oc.,tw.,md.,ad.,cu.,pr.,dc.).
- Parameters:
value (str) – The color string to parse. Surrounding whitespace is stripped.
- Return type:
- Raises:
TypeError – If
valueis not astr.ValueError – If a functional form has the wrong number of arguments, non-numeric arguments, or the underlying factory rejects the value.
- property rgb: RgbView¶
Get RGB view of the color.
- Returns:
View object for RGB color space access.
- Return type:
Examples
>>> import dartwork_mpl as dm >>> color = dm.rgb(0.8, 0.2, 0.3) >>> >>> # Attribute access >>> r = color.rgb.r >>> g = color.rgb.g >>> >>> # Unpacking >>> r, g, b = color.rgb >>> >>> # Writing >>> color.rgb.r = 0.9
- to_hex() str[source]¶
Convert to hex color string.
- Returns:
Hex color string (#RRGGBB).
- Return type:
str
- to_oklab() tuple[float, float, float][source]¶
Convert to OKLab coordinates.
- Returns:
(L, a, b) OKLab coordinates.
- Return type:
tuple[float, float, float]
- to_oklch() tuple[float, float, float][source]¶
Convert to OKLCH coordinates.
- Returns:
(L, C, h) OKLCH coordinates, where h is in degrees [0, 360).
- Return type:
tuple[float, float, float]
- to_rgb() tuple[float, float, float][source]¶
Convert to RGB values.
- Returns:
(r, g, b) sRGB values in range [0, 1].
- Return type:
tuple[float, float, float]
Notes
Colors inside the sRGB gamut convert exactly. Out-of-gamut colors are gamut-mapped by reducing chroma while holding lightness (L) and hue (h) fixed — a binary search to the sRGB gamut boundary along the requested OKLCH hue line (CSS Color 4 style) — so the rendered color keeps the requested L and h instead of the per-channel clamp’s L/h drift. A final per-channel clamp absorbs sub-tolerance boundary residual and clips an achromatic L outside
[0, 1](which chroma reduction alone cannot represent). Usein_gamut()to detect whether a color required mapping.
- class dartwork_mpl._colors.OklabView(color: Color)[source]¶
Bases:
_BaseColorViewView class for OKLab color space access.
Provides attribute-based access to OKLab coordinates (L, a, b) with support for reading, writing, unpacking, and indexing.
- Parameters:
color (Color) – The Color instance to view.
Examples
>>> import dartwork_mpl as dm >>> color = dm.oklab(0.7, 0.1, 0.2) >>> >>> # Attribute access >>> L = color.oklab.L >>> a = color.oklab.a >>> >>> # Unpacking >>> L, a, b = color.oklab >>> >>> # Indexing >>> a = color.oklab[1] >>> >>> # Writing >>> color.oklab.L += 0.1 >>> color.oklab.a = 0.2
- property L: float¶
Lightness component.
- property a: float¶
Green-red component.
- property b: float¶
Blue-yellow component.
- dartwork_mpl._colors.OklabViewIterator¶
alias of
_ColorViewIterator
- class dartwork_mpl._colors.OklchView(color: Color)[source]¶
Bases:
_BaseColorViewView class for OKLCH color space access.
Provides attribute-based access to OKLCH coordinates (L, C, h) with support for reading, writing, unpacking, and indexing.
- Parameters:
color (Color) – The Color instance to view.
Examples
>>> import dartwork_mpl as dm >>> color = dm.oklch(0.7, 0.2, 120) >>> >>> # Attribute access >>> L = color.oklch.L >>> C = color.oklch.C >>> h = color.oklch.h >>> >>> # Unpacking >>> L, C, h = color.oklch >>> >>> # Indexing >>> C = color.oklch[1] >>> >>> # Writing >>> color.oklch.C *= 1.2 >>> color.oklch.h = 180
- property C: float¶
Chroma component.
- property L: float¶
Lightness component.
- property h: float¶
Hue component in degrees [0, 360).
- dartwork_mpl._colors.OklchViewIterator¶
alias of
_ColorViewIterator
- class dartwork_mpl._colors.RgbView(color: Color)[source]¶
Bases:
_BaseColorViewView class for RGB color space access.
Provides attribute-based access to RGB coordinates (r, g, b) with support for reading, writing, unpacking, and indexing.
- Parameters:
color (Color) – The Color instance to view.
Examples
>>> import dartwork_mpl as dm >>> color = dm.rgb(0.8, 0.2, 0.3) >>> >>> # Attribute access >>> r = color.rgb.r >>> g = color.rgb.g >>> >>> # Unpacking >>> r, g, b = color.rgb >>> >>> # Indexing >>> g = color.rgb[1] >>> >>> # Writing >>> color.rgb.r = 0.9 >>> color.rgb.g += 0.1
- property b: float¶
Blue component [0, 1].
- property g: float¶
Green component [0, 1].
- property r: float¶
Red component [0, 1].
- dartwork_mpl._colors.RgbViewIterator¶
alias of
_ColorViewIterator
- dartwork_mpl._colors.color(value: Color | str) Color[source]¶
Parse a string (or pass through a
Color) into aColor.String-parser counterpart to
hex(),rgb(),oklch(),oklab(), and palette-name lookup. Mirrorsdartwork_mpl.length()for unit strings.Examples
>>> import dartwork_mpl as dm >>> dm.color("#ff0000") # hex >>> dm.color("rgb(1, 0, 0)") # functional >>> dm.color("oklch(0.7, 0.15, 30)") >>> dm.color("oc.red5") # palette name
- Parameters:
value (Color or str) – A
Colorinstance is returned as a fresh copy with the same OKLab coordinates. A string is dispatched throughColor.parse().- Return type:
- dartwork_mpl._colors.colors(name: str, n: int | None = None, *, reverse: bool = False) Colormap | list[str][source]¶
Return a Model B colormap or designed discrete color form.
Bare family names (
"aurora") and registered names ("dc.aurora") are equivalent.n=Nonereturns the matplotlib colormap for that family;n=intreturns the deterministic designed discrete form as hex strings.
- dartwork_mpl._colors.cspace(start_color: Color | str, end_color: Color | str, n: int, space: str = 'oklch') list[Color][source]¶
Interpolate between two colors to produce a list of evenly spaced colors.
Similar to numpy’s
linspace, but operating in color space.- Parameters:
start_color (Color | str) – Starting color (Color instance or hex string).
end_color (Color | str) – Ending color (Color instance or hex string).
n (int) – Total number of colors to generate (including start and end).
space (str, optional) – Color space for interpolation: ‘oklch’ (default), ‘oklab’, or ‘rgb’. ‘oklch’ produces the most perceptually uniform results.
- Returns:
List of interpolated Color objects.
- Return type:
list[Color]
- Raises:
TypeError – If start_color or end_color is not a Color instance or hex string.
ValueError – If an unsupported color space is specified.
- dartwork_mpl._colors.ensure_contrast(color: Any, background: Any, *, min_ratio: float = 4.5) str[source]¶
Adjust a color until it reaches a minimum contrast ratio.
coloris returned unchanged when it already meetsmin_ratio. Otherwise the color’s HLS lightness is moved toward the pole, black or white, that gives the stronger WCAG contrast againstbackground. Hue and saturation are held constant while a binary search finds the smallest deterministic lightness change that reaches the requested ratio, or the pole if the requested ratio is unreachable.- Parameters:
color (color-like) – Foreground color accepted by Matplotlib.
background (color-like) – Background color accepted by Matplotlib.
min_ratio (float, optional) – Minimum WCAG contrast ratio to satisfy. Default
4.5.
- Returns:
colorunchanged when it already passes and is a string; otherwise an adjusted"#rrggbb"color.- Return type:
str
- Raises:
ValueError – If
min_ratiois not a positive finite number.
Examples
>>> ensure_contrast("#ddddaa", "white") '#7a7a31' >>> ensure_contrast("black", "white") 'black'
- dartwork_mpl._colors.hex(hex_str: str) Color[source]¶
Convenience wrapper to create a Color from a hex string.
- Parameters:
hex_str (str) – Hex color code string (#RGB or #RRGGBB format).
- Returns:
A new Color instance.
- Return type:
Notes
This is the public
dm.hexconstructor and intentionally shares the name of the builtinhex. The shadow is scoped to this module / thedartwork_mplnamespace; usebuiltins.hexif you need the integer-to-hex builtin alongside it.
- dartwork_mpl._colors.list_colors(kind: Literal['sequential', 'multi-hue', 'diverging', 'cyclic', 'qualitative'] | str | None = None) list[dict[str, object]][source]¶
List Model B color families and their metadata.
- dartwork_mpl._colors.oklab(L: float, a: float, b: float) Color[source]¶
Convenience wrapper to create a Color from OKLab coordinates.
- Parameters:
L (float) – OKLab color coordinates.
a (float) – OKLab color coordinates.
b (float) – OKLab color coordinates.
- Returns:
A new Color instance.
- Return type:
- dartwork_mpl._colors.oklch(L: float, C: float, h: float) Color[source]¶
Convenience wrapper to create a Color from OKLCH coordinates.
- Parameters:
L (float) – Lightness and chroma values.
C (float) – Lightness and chroma values.
h (float) – Hue angle in degrees [0, 360).
- Returns:
A new Color instance.
- Return type:
- dartwork_mpl._colors.readable_text_color(background: Any, *, light: str | None = None, dark: str | None = None, threshold: float | None = None) str[source]¶
Choose the more readable text color for a background.
- Parameters:
background (color-like) – Background color accepted by Matplotlib.
light (str or None, optional) – Candidate light ink.
Noneuses the library’s standard light ink,"white". DefaultNone.dark (str or None, optional) – Candidate dark ink.
Noneuses the standard dark text color inherited by the light style presets,"black". DefaultNone.threshold (float or None, optional) – Accepted for compatibility with threshold-based callers. Selection is always based on the higher WCAG contrast ratio. Default
None.
- Returns:
The selected ink color string, either
lightordark.- Return type:
str
Examples
>>> readable_text_color("#222222") 'white' >>> readable_text_color("#f7f7f7") 'black'
- dartwork_mpl._colors.rgb(r: float, g: float, b: float) Color[source]¶
Convenience wrapper to create a Color from RGB values.
- Parameters:
r (float) – RGB color values (auto-detected as [0-1] or [0-255] range).
g (float) – RGB color values (auto-detected as [0-1] or [0-255] range).
b (float) – RGB color values (auto-detected as [0-1] or [0-255] range).
- Returns:
A new Color instance.
- Return type:
- dartwork_mpl._colors.set_colors(name_or_list: str | Iterable[str] | None = None, *, ax: Axes | None = None, n: int | None = None, styles: bool = False) None[source]¶
Set the matplotlib color cycle from a Model B family or explicit list.
- dartwork_mpl._colors.show_colors(kind: Literal['sequential', 'multi-hue', 'diverging', 'cyclic', 'qualitative'] | str | None = None, names: Iterable[str] | None = None, n: int | None = None) Figure[source]¶
Return a compact preview figure for Model B color families.
Note
mix_colors and pseudo_alpha are defined in the util module
but re-exported from the top-level dartwork_mpl namespace for
convenience alongside other color helpers.
- dartwork_mpl.mix_colors(color1: str | tuple[float, float, float], color2: str | tuple[float, float, float], alpha: float = 0.5) tuple[float, float, float][source]¶
Blend two colors in OKLab space (perceptually uniform blend).
Blends in OKLab rather than gamma-encoded sRGB, so midpoints avoid the “muddy” saturation dip that naive RGB mixing produces for saturated hues (e.g. red + blue → purple, not a dark desaturated grey).
- Parameters:
color1 (str | tuple[float, float, float]) – First color to blend. Any format recognized by matplotlib.
color2 (str | tuple[float, float, float]) – Second color to blend. Any format recognized by matplotlib.
alpha (float, optional) – Weight of color1 (0 → color2, 1 → color1). Default is 0.5.
- Returns:
sRGB tuple of the blended result, compatible with any matplotlib
color=argument.- Return type:
tuple[float, float, float]
- Raises:
ValueError – If
alphais not a finite number in[0, 1]. Values outside the closed interval extrapolate and gamut-clamp to a plausible-looking but wrong colour (e.g.alpha=2yields salmon for a red/blue blend), so they are rejected rather than silently returned.
Notes
The result will differ subtly from previous versions for non-grayscale blends — gradients now look smoother and less desaturated through saturated midpoints.
dm.pseudo_alpha(which delegates to this function) inherits the same improvement.
- dartwork_mpl.pseudo_alpha(color: str | tuple[float, float, float], alpha: float = 1.0, background: str | tuple[float, float, float] = 'white') tuple[float, float, float][source]¶
Return an opaque RGB that simulates alpha transparency against a background.
True alpha can cause darkening artifacts when lines overlap or cover images. This function blends the color with the background to produce a flat (opaque) color that visually mimics transparency.
- Parameters:
color (str | tuple[float, float, float]) – The target foreground color.
alpha (float, optional) – Simulated opacity (0 to 1). Default is 1.0 (fully opaque).
background (str | tuple[float, float, float], optional) – Background color to blend against. Default is “white”.
- Returns:
RGB tuple of the composited color.
- Return type:
tuple[float, float, float]
Color Interpolation¶
- dartwork_mpl.cspace(start_color: Color | str, end_color: Color | str, n: int, space: str = 'oklch') list[Color][source]¶
Interpolate between two colors to produce a list of evenly spaced colors.
Similar to numpy’s
linspace, but operating in color space.- Parameters:
start_color (Color | str) – Starting color (Color instance or hex string).
end_color (Color | str) – Ending color (Color instance or hex string).
n (int) – Total number of colors to generate (including start and end).
space (str, optional) – Color space for interpolation: ‘oklch’ (default), ‘oklab’, or ‘rgb’. ‘oklch’ produces the most perceptually uniform results.
- Returns:
List of interpolated Color objects.
- Return type:
list[Color]
- Raises:
TypeError – If start_color or end_color is not a Color instance or hex string.
ValueError – If an unsupported color space is specified.
Model B Color API¶
- dartwork_mpl.colors(name: str, n: None = None, *, reverse: bool = False) Colormap[source]¶
- dartwork_mpl.colors(name: str, n: int, *, reverse: bool = False) list[str]
Return a Model B colormap or designed discrete color form.
Bare family names (
"aurora") and registered names ("dc.aurora") are equivalent.n=Nonereturns the matplotlib colormap for that family;n=intreturns the deterministic designed discrete form as hex strings.
- dartwork_mpl.set_colors(name_or_list: str | Iterable[str] | None = None, *, ax: Axes | None = None, n: int | None = None, styles: bool = False) None[source]¶
Set the matplotlib color cycle from a Model B family or explicit list.