fix: preserve interpolation through construction and with_extremes() - #150
Draft
matthiasschabel wants to merge 2 commits into
Draft
fix: preserve interpolation through construction and with_extremes()#150matthiasschabel wants to merge 2 commits into
matthiasschabel wants to merge 2 commits into
Conversation
The last line of Colormap.__init__ wrote the requested interpolation mode into the ColorStops it was handed, and that object often belongs to someone else: _parse_colorstops returns a ColorStops argument unchanged, and the Colormap branch takes value.color_stops directly. Constructing a linear colormap from a nearest one therefore switched the source to linear rendering while its own `interpolation` attribute kept reporting "nearest". The result now gets a shallow copy carrying its own mode, made only when the mode differs. Shallow rather than rebuilt, because rebuilding from `_lut_func` would call the user's callable a second time. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Reviewed-By: Codex (gpt-5.6-sol, reasoning effort xhigh)
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #150 +/- ##
==========================================
+ Coverage 95.56% 95.57% +0.01%
==========================================
Files 168 168
Lines 2186 2192 +6
==========================================
+ Hits 2089 2095 +6
Misses 97 97 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
with_extremes() forwards name and category but not interpolation, and _norm_interp(None) is "linear", so it asserted "linear" over whatever the source had. A single call turned a discrete colormap into a continuous one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Reviewed-By: Codex (gpt-5.6-sol, reasoning effort xhigh)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two ways a colormap's interpolation mode goes missing.
The constructor writes into stops it does not own. The last line of
Colormap.__init__sets the requested mode on theColorStopsit was handed (src/cmap/_colormap.py:309), and that object usually belongs to the caller:_parse_colorstopsreturns aColorStopsargument unchanged (:1509), and theisinstance(value, Colormap)branch takesvalue.color_stopsdirectly (:300).The source keeps reporting
"nearest"while rendering"linear", so the object contradicts itself and nothing raises.with_extremes()drops the mode. It forwardsnameandcategorybut notinterpolation, and_norm_interp(None)is"linear", so one call converts a discrete colormap to a continuous one. An ordered class scheme likecolorbrewer:Blues_9starts blending between classes afterwith_extremes(bad=...).The fixes are a shallow copy carrying its own mode, made only when the mode actually differs, and one added argument in
with_extremes.Shallow rather than rebuilt from scratch: a
ColorStopscan be backed by a userlut_func, and reconstructing would call that callable a second time over 256 values. Callables are part of the publicColormapLikeAPI with no purity requirement, so a second call is neither free nor necessarily harmless.A related issue probably requiring maintainer input:
with_extremesalso dropsidentifier. It's unclear whether an omittedbad/under/overshould clear the existing one or leave it.