Generate perceptually uniform colour ramps for data visualisation.
datahues creates smooth, perceptually uniform colour gradients from a start colour to an end colour. Unlike simple RGB or HSL interpolation, which can produce visually uneven ramps, this library leverages the Oklab colour space: a perceptually uniform space where equal mathematical changes correspond to equal perceptual colour differences.
A comparison of a linear RGB colour ramp (generated with matplotlib's LinearSegmentedColormap.from_list) versus an Oklab-interpolated ramp generated by datahues. The start and end colours here are #F61212 ("Pure Red") and #12F612 ("Lime").
The figure above demonstrates why it's important to think about perceptual uniformity of colour ramps. If you naïvely interpolate in RGB space between two colours, you end up with a ramp that gives you artificial banding (cf. left panel). You might then see patterns in your data that aren't truly there!
datahues is available on PyPI and conda-forge.
Install from PyPI with pip:
pip install datahuesInstall from conda-forge with conda, setting the conda-forge channel:
conda install -c conda-forge datahuesdatahues just has two public functions: generate_hex_list and generate_cmap. Both generate a sequential colour ramp given start and end colour hexes. The former returns a list of hexes, and the latter returns a matplotlib LinearSegmentedColormap object.
Between start and end colours, generates a list of hex colour codes representing points along a smooth colour ramp. It is assumed the user wants a discrete number (n_stops) of points, so no warning is given when n_stops is small (unlike in generate_cmap below). However, if these hexes are being used to create a continuous colour ramp, it is recommended to use n_stops>=128.
- Parameters:
start_hex: Starting colour as hex code (e.g.,"#FF0000")end_hex: Ending colour as hex code (e.g.,"#0000FF")n_stops: Number of colour stops in the ramp (default: 512)
- Returns: List of hex colour codes representing the gradient
Betweem start and end colours, creates a matplotlib LinearSegmentedColormap object, forming a smooth colour ramp.
- Parameters:
start_hex,end_hex,n_stops: As abovename: The "name" of the colour ramp for matplotlib internal purposes (default: "interp_ramp")
- Returns:
LinearSegmentedColormapobject ready to use in matplotlib visualisation - Warning:
n_stops < 128may produce visible banding; use larger values for smoother results
The library converts colours through multiple colour spaces to achieve perceptual uniformity:
- Hex → RGB — Parse hex codes into normalised [0.0, 1.0] RGB values
- RGB → XYZ — Apply gamma correction and convert to CIE XYZ (D65 illuminant)
- XYZ → Oklab — Convert through LMS intermediate space to Oklab (perceptually uniform)
- Interpolate in Oklab — Create evenly-spaced values in perceptual space
- Oklab → RGB → Hex — Reverse conversion back to hex color codes
This approach ensures that visual transitions between colours feel smooth and natural across the entire gradient.
The list below has some ideas for future features to be implemented in datahues. No promises!
- Colour sequences with more than 2 colours.
- Alternative colour spaces (beyond Oklab)
- Alternative input types (besides hex codes), e.g. matplotlib colour names or RGB tuples.
Feel free to get in touch / make an issue with other requests.
