Skip to content

feat: add register_mpl function to register colormaps with matplotlib - #162

Merged
tlambert03 merged 3 commits into
pyapp-kit:mainfrom
tlambert03:register-mpl
Oct 20, 2026
Merged

tlambert03 merged 3 commits into
pyapp-kit:mainfrom
tlambert03:register-mpl

Conversation

@tlambert03

@tlambert03 tlambert03 commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

thanks @cvanelteren (and @beskep for the context in Ultraplot/UltraPlot#491).

I'd think I'd rather not register the entire cmap catlog with mpl on import: cmap can end up imported as a dependency of some other library, so an mpl user could have it in their session without knowing, and suddenly see ~1300 extra entries in plt.colormaps(), the Qt figure options dropdown, etc. Not to mention it would increase cmap import time 100 fold (from ~12 ms to 1 sec). (By contrast, cmasher only registers ~100)

So instead, this adds an explicit function:

import cmap

cmap.register_mpl("tol:*", "batlow")  # names or fnmatch patterns

plt.imshow(data, cmap="tol:bright")
plt.imshow(data, cmap="crameri:batlow_r")  # _r versions too

It only registers fully-qualified namespace:name keys and skips anything already registered. Names are canonical (lowercase, _ not -), so tol:bright_alt, not tol:bright-alt. I checked it with ultraplot 2.7.1: after cmap.register_mpl("tol:bright") or cmap.register_mpl("tol:*"), uplt.rc["cmap.qualitative"] = "tol:bright" works (without it, it raises a KeyError).

I'd caution against running cmap.register_mpl("*") at your own import time. If you'd rather not require users to call anything, another option on the UltraPlot side would be a lazy fallback when a key isn't found... something like this (untested sketch) in ColormapDatabase.__getitem__:

if not self._has_item(key):
    try:
        import cmap

        self.register(cmap.Colormap(key).to_mpl(), name=key)
    except (ImportError, ValueError):
        pass  # fall through to the usual KeyError

Thoughts? Does this solve your needs? Or are you really hoping for the full cmap catalog to be registered?

@codecov

codecov Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.45455% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 95.90%. Comparing base (a9eab0b) to head (9fabe14).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/cmap/_util.py 95.23% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #162      +/-   ##
==========================================
- Coverage   95.91%   95.90%   -0.01%     
==========================================
  Files         168      168              
  Lines        2252     2273      +21     
==========================================
+ Hits         2160     2180      +20     
- Misses         92       93       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cvanelteren

Copy link
Copy Markdown

Hi @tlambert03 thanks for the quick turn around. I think for now this would suffice. We at ultraplot can register colormaps lazily, but matplotlib does not have this feature. I was not aware that the registration was so big on cmap's end! One way around the registration taking long would be to allow a lazy subclass to exist

from matplotlib.colors import Colormap

class LazyColormap(Colormap):
    def __init__(self, name, factory):
        super().__init__(name)
        self._factory = factory
        self._real = None

    def _load(self):
        if self._real is None:
            self._real = self._factory()
        return self._real

    def __call__(self, X, alpha=None, bytes=False):
        return self._load()(X, alpha=alpha, bytes=bytes)

Then this proxy would resolve on load. I think this may mittigate the loading taking long on cmap's end and should be compatible with mpl and ultraplot.

@tlambert03
tlambert03 merged commit 57e3a13 into pyapp-kit:main Oct 20, 2026
18 of 20 checks passed
@tlambert03
tlambert03 deleted the register-mpl branch October 20, 2026 11:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants