Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

ENH/API: improvements to register_cmap #15127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 25, 2020

Conversation

tacaswell
Copy link
Member

  • protect re-defining built in color maps

  • warn on re-defining user-defined color maps

  • add de-register function

  • Has Pytest style unit tests

  • Code is Flake 8 compliant

  • New features are documented, with examples if plot related

  • Documentation is sphinx and numpydoc compliant

  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)

  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

doc/users/next_whats_new/2019-08_tac.rst Outdated Show resolved Hide resolved
lib/matplotlib/cm.py Outdated Show resolved Hide resolved
@tacaswell tacaswell added this to the v3.3.0 milestone Aug 26, 2019
lib/matplotlib/tests/test_cm.py Outdated Show resolved Hide resolved
@ImportanceOfBeingErnest
Copy link
Member

The general idea seems that matplotlib encourages a lot of third party packages to spawn in the wild, each with one or more colormaps, and each registering their colormaps via the cm module. Because there is easily some overlap between those to be expected (package 1 has "rocket", "moon" and "silveraqua", package 2 has "rocket" and "desertnight", user needs to import both because they need "silveraqua" and "desertnight"), there should be a solution that allows both packages to be imported without error. Even the warning might be annoying, in case "rocket" from package 1 and "rocket" from package 2 are in fact identical.

@anntzer
Copy link
Contributor

anntzer commented Aug 26, 2019

Perhaps we should just not use string names and instead use normal qualified python names (mypackage.mycmap)...


edit to clarify: If you're going to need an import to trigger the registration, you already have the module imported, so it's just as good to access an attribute from that module; because module names are unique (in a flat namespace), this handles the problem of name collision for us.
... and, per @jklymak's comment below, now you don't even need to have a registration API.

@jklymak
Copy link
Member

jklymak commented Aug 26, 2019

As a meta comment, I mess w colormaps all the time and don’t ever bother registering them. But maybe that’s because I’ve never bothered to set up my own startup package. Agree w @ImportanceOfBeingErnest that being able to override colormap names should be allowed. If I want to replace jet with turbo and call it jet, why not?

Overall, what is the end-user interface for colormaps? We really could use documentation on this. Are we all supposed to have our own pip installable packages myplottingsettings ? This feeds into the python matplotlibrc question

@ImportanceOfBeingErnest
Copy link
Member

In order to not be misunderstood here: I did not say one should allow for matplotlib's colormaps to be overridden. In fact a protection layer like the one proposed in this PR makes perfect sense. My comment above was about not protecting additional/external colormaps; or at least find a solution for the case that several packages try to register the same colormap under the same name.

Copy link
Contributor

@dopplershift dopplershift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with the warning. We don't want it to be a hard exception (because that could lead to other packages failing to import).

@timhoffm
Copy link
Member

Flake8:

./lib/matplotlib/cm.py:30:1: E302 expected 2 blank lines, found 1

lib/matplotlib/cm.py Outdated Show resolved Hide resolved
doc/api/next_api_changes/2019-08-19-TAC.rst Outdated Show resolved Hide resolved
@tacaswell
Copy link
Member Author

Moved to new doc scheme and took @dstansby 's completion of the sentence.

lib/matplotlib/tests/test_cm.py Outdated Show resolved Hide resolved
Copy link
Member

@timhoffm timhoffm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this is an improvement:

  • Protecting builtin colormaps is our original interest.
  • Warning on overwriting colormaps is also reasonable as one might otherwise have surprising effects.
  • Unregistering is a way of silencing the above warning. There may be use cases, but it's not without problems because the same name may be used by multiple packages.
    • I've proposed a note to at least make users aware of the issues.
    • Name clashes could have happend before and that problem is not solved by unregister.
      Still it's good to have an official function for that.

Not addressed by this PR:

  • Strategies of name clashes and their handling.

lib/matplotlib/cm.py Show resolved Hide resolved
@QuLogic
Copy link
Member

QuLogic commented May 4, 2020

Where do we stand on this in light of #16943 and other discussions in the meeting?

@tacaswell tacaswell modified the milestones: v3.3.0, v3.4.0 May 11, 2020
@timhoffm
Copy link
Member

This is orthogonal to #16943. While #16943 addresses modification of the default colormap objects, this here addresses replacing default colormap objects.

@jklymak jklymak marked this pull request as draft August 24, 2020 14:58
@jklymak
Copy link
Member

jklymak commented Aug 24, 2020

This has three approvals - just needs a rebase?

@jklymak
Copy link
Member

jklymak commented Sep 24, 2020

If one of the original reviewers had a minute to re-review, I think that would be adequate to merge.

@jklymak
Copy link
Member

jklymak commented Sep 24, 2020

Sorry, I'll explicitly ping because I'm not sure that re-requests show up in folks' feeds: @dopplershift @timhoffm @dstansby Thanks!

Copy link
Contributor

@dopplershift dopplershift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still good with these changes. Just some minor copy-editing, mainly for consistency.

lib/matplotlib/cm.py Outdated Show resolved Hide resolved
lib/matplotlib/cm.py Outdated Show resolved Hide resolved
lib/matplotlib/cm.py Outdated Show resolved Hide resolved
lib/matplotlib/cm.py Outdated Show resolved Hide resolved
lib/matplotlib/cm.py Outdated Show resolved Hide resolved
lib/matplotlib/cm.py Outdated Show resolved Hide resolved
lib/matplotlib/cm.py Outdated Show resolved Hide resolved
lib/matplotlib/cm.py Outdated Show resolved Hide resolved
lib/matplotlib/cm.py Outdated Show resolved Hide resolved
lib/matplotlib/tests/test_colors.py Outdated Show resolved Hide resolved
Otherwise we will hand a view back to the user and it will change
under them if `set_under` (e.g.) is called.
This was deprecated in 3.3 via matplotlib#15875

Enforce type of cmap as Colormap because we may not know that the
object registered is of the wrong type until well after it was
registered, defensively check here.

We could do a duck-type check, but this is much simpler and we can
cross the bridge of writing a duck-type checking function when someone
has a use case for registering
compatible-but-not-derived-from-Colormap instances.
@timhoffm timhoffm self-assigned this Sep 25, 2020
@tacaswell tacaswell force-pushed the register_cmap_test branch 2 times, most recently from 3790fd7 to 4089b2c Compare September 25, 2020 01:26
@tacaswell
Copy link
Member Author

ok, fixed and squashed down to 3 non-embarrassing commits (I was apparently working a bit longer than my brain was useful last night...).

doc/api/next_api_changes/behavior/15127-TAC.rst Outdated Show resolved Hide resolved
 - raise if you try to over write a default colormap
 - warn if you try to over write a user-added colormap
 - add method to de-register a color map
 - add escape hatch to force re-registering builtin colormaps

Co-Authored-By: David Stansby <dstansby@gmail.com>
@dopplershift dopplershift merged commit 6aca58e into matplotlib:master Sep 25, 2020
@tacaswell tacaswell deleted the register_cmap_test branch September 25, 2020 18:45
@pauldmccarthy
Copy link

Hi all, I recently got bitten by this change (my fault for not keeping my CI images up to date with the latest matplotlib). I am curious about the use of override_builtin option. Is this going to be removed in a future version of matplotlib, or can I rely on using it?

I maintain a MRI image viewer which comes with a collection of built in colour maps that, for historical reasons, use the same names as some built-in matplotlib colour maps, and am wondering about the best way to tackle this change in matplotlib. Thanks!

@tacaswell
Copy link
Member Author

@pauldmccarthy At this point I think you can rely on it being there, but re-affirm the note in the docstring "please only use this if you are sure you need it"!

@pauldmccarthy
Copy link

@tacaswell Yes, that particular note is why I was asking :)

I'd thought of working around this by "salting" my own colour maps with a unique prefix, but I maintain my own colourmap registry (just containing the colour maps specific to my application) alongside matplotlib.cm, and have a fair amount of code which assumes that the identifiers are the same in both registries. So I was hoping to, at the very least, delay having to re-factor things. Generally my project is used as a stand-alone application, so there is not much of a concern in conflicting with other libraries that also use matplotlib.cm.register_cmap. But I will probably revisit this at some point to do things a bit more cleanly. Thanks for the reply :)

@tacaswell
Copy link
Member Author

That makes sense in the context of an application. "historical reasons" is something I have great personal sympathy with :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.