Skip to main content

CI codecov

Melanopy: A melanopic axis for colormaps

Scientific colormaps are usually judged on two axes: perceptual uniformity and colour-vision-deficiency (CVD) safety. Melanopy adds a third: how much short-wavelength, melanopic (melatonin-suppressing) light a map emits. Unlike the other two, this third axis is a design dimension you choose by context, not a pass/fail gate — a sleep lab wants its protective end, a daytime alerting display the other. Melanopy makes the axis measurable, scores existing colormaps on it, and provides a one-parameter family that walks it while holding uniformity and CVD-safety fixed.

For people who read screens as their main light source at night (e.g., sleep labs, observatories, NICU, night radiology, control rooms) large data-fills (e.g., spectrograms, density maps) actually emit light, and their colour content can cooperate with, or fight, a chosen circadian lighting strategy.

This rates a colour's chromaticity, not light dose. Real circadian load also depends on screen brightness, screen fill, viewing distance, and ambient light. If you genuinely need to stay alert, the dominant lever is room lighting. The value here is measurability, a scored index, a uniformity-preserving generator, and surfacing the axis. The physiological effect of a colormap alone is second-order.

📖 Documentation: https://remrama.github.io/melanopy

Quickstart

import matplotlib.pyplot as plt
import numpy as np

import melanopy as mp

# Score any colormap on the melanopic axis  (display white = 1.0)
c = plt.get_cmap("viridis")(np.linspace(0, 1, 256))[:, :3]
print(mp.rate_colormap(c))
# {'melanopic_ratio': ~0.83, 'mp_spread': ..., 'range': (...)}

# Use the named endpoints (registered with matplotlib) on any 2-D field Z
mp.register()
Z = np.add.outer(np.linspace(0, 1, 200), np.linspace(0, 1, 200))
plt.imshow(Z, cmap="sodium")    # protective: warm, low-melanopic
plt.imshow(Z, cmap="xenon")     # alerting:   cool, high-melanopic
plt.imshow(Z, cmap="equilux")   # circadian-neutral (M/P ~ 1)

# Dial the whole axis: alpha 0 (protective) .. 1 (alerting)
cmap = mp.circadia(0.3, as_cmap=True)

# Or walk the whole axis in one map, or diverge for signed data
seq = mp.circadia_sweep()        # protective -> alerting; melanopic ratio ~linear in the data
div = mp.circadia_diverging()    # signed: warm protective <- neutral -> cool alerting

melanopic_ratio < 1 → protective (warm); > 1 → alerting (cool/blue).

The two metrics

  • M/P mean (melanopic_ratio) — where a map sits on the axis (white = 1).
  • M/P spread (σ) (mp_spread) — how tightly it sits. A map can be mildly protective on average yet smeared (e.g. viridis dumps blue at its dark end); a tight spread reads as a "pure" ramp. Both numbers are luminance-weighted, so near-black pixels that emit almost nothing don't dominate either one.

What scoring the existing maps reveals

Applying the rater to the colormaps people already use settles how much new design is even needed — three non-obvious facts fall out (full table in index/):

  • A protective, pure map already exists — copper (M/P 0.49, σ 0.03) and sodium (0.29); the protective end just needed naming, not inventing.
  • The popular uniform maps are smeared — viridis / magma / inferno / cividis / plasma sit mid-axis but dump high-melanopic blue at their dark, low-data end (σ ≈ 0.4–1.0).
  • The genuine gap is a uniform, CVD-safe alerting map — the slot the Circadia family's xenon endpoint is built to fill.

Scope & novelty

  • Borrowed — the melanopic metrology: the CIE S 026 melanopic action spectrum + V(λ), validated against the luox reference calculator (melanopy reproduces the CIE S 026 D65 constant to five significant figures — see manuscript/luox_crosscheck.md).
  • New — the port to colormaps: the per-display three-coefficient collapse (any sRGB colour → a weighted sum of three per-primary M/P numbers, so no runtime spectral integration); the mean + spread decomposition that catches "smeared" maps; and the constraint-preserving generator in which melanopic content is emergent, never optimized.

Display panels

Melanopic content depends on the display's primary spectra, which sRGB doesn't fix — so the rater takes a panel= argument selecting among representative archetypes (representative narrowband, led_lcd blue-pump white-LED, oled, wide_gamut quantum-dot). Absolute M/P shifts with the panel (the blue coefficient ranges ≈8.8 to ≈13.7), but the ranking is robust: Spearman ρ ≥ 0.99 across panels, and display white stays exactly 1.0 (see index/). For exact numbers on a specific monitor, plug its measured primary SPDs into melanopy.spectra.coefficients_from_primaries.

Metadata

Release files for melanopy 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for melanopy 0.0.1
File Size Uploaded Provenance Actions
melanopy-0.0.1.tar.gz 41.2 kB With provenance Details for melanopy-0.0.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for melanopy 0.0.1
File Interpreter ABI Platform Actions
melanopy-0.0.1-py3-none-any.whl Python 3 none any Details for melanopy-0.0.1-py3-none-any.whl

Total release size: 76.3 kB

Release files / melanopy-0.0.1.tar.gz

Download URL melanopy-0.0.1.tar.gz
Size 41.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e72782cd3afa4a4c1b7c27e7e0e4a4f7852fcf1e82d75fa32f9971a55c16a850
BLAKE2b-256 checksum
How to use checksums
e02ba13eb87cadb595ee6d070bfbc6168f663ad3549d140ea744cc57c909e4a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 5, 2026.

Transparency log

Release files / melanopy-0.0.1-py3-none-any.whl

Download URL melanopy-0.0.1-py3-none-any.whl
Size 35.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d4207d7dd4a5cf82b2d2814756e20852daf7838f68efb17bec967d256bb70ad6
BLAKE2b-256 checksum
How to use checksums
ca6a9ace3348bb78cf84b910987e6bc0bb5864187cb4b769464a7692bd21a569
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 5, 2026.

Transparency log

Security for melanopy 0.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for melanopy-0.0.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 5, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page