| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| Colormap registry | ||
| ------------------ | ||
|
|
||
| Colormaps are now managed via `matplotlib.colormaps`, which is a | ||
| `.ColormapRegistry`. | ||
|
|
||
| Colormaps can be obtained using item access:: | ||
|
|
||
| import matplotlib as mpl | ||
| cmap = mpl.colormaps['viridis'] | ||
|
|
||
| To register new colormaps use:: | ||
|
|
||
| mpl.colormaps.register(my_colormap) | ||
|
|
||
| The use of `matplotlib.cm.get_cmap` and `matplotlib.cm.register_cmap` is | ||
| discouraged in favor of the above. Within `.pyplot` the use of | ||
| ``plt.get_cmap()`` and ``plt.register_cmap()`` will continue to be supported. |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| Expand Up | @@ -15,7 +15,7 @@ | |||||||
| normalization. | ||||||||
| """ | ||||||||
|
|
||||||||
| from collections.abc import MutableMapping | ||||||||
| from collections.abc import Mapping, MutableMapping | ||||||||
|
|
||||||||
| import numpy as np | ||||||||
| from numpy import ma | ||||||||
| Expand Down Expand Up | @@ -91,13 +91,86 @@ def _warn_deprecated(self): | |||||||
| ) | ||||||||
|
|
||||||||
|
|
||||||||
| class ColormapRegistry(Mapping): | ||||||||
| r""" | ||||||||
| Container for colormaps that are known to Matplotlib by name. | ||||||||
|
|
||||||||
| The universal registry instance is `matplotlib.colormaps`. There should be | ||||||||
| no need for users to instantiate `.ColormapRegistry` themselves. | ||||||||
|
|
||||||||
| Read access uses a dict-like interface mapping names to `.Colormap`\s:: | ||||||||
|
|
||||||||
| import matplotlib as mpl | ||||||||
| cmap = mpl.colormaps['viridis'] | ||||||||
|
|
||||||||
| Returned `.Colormap`\s are copies, so that their modification does not | ||||||||
| change the global definition of the colormap. | ||||||||
|
|
||||||||
| Additional colormaps can be added via `.ColormapRegistry.register`:: | ||||||||
|
|
||||||||
| mpl.colormaps.register(my_colormap) | ||||||||
| """ | ||||||||
| def __init__(self, cmaps): | ||||||||
| self._cmaps = cmaps | ||||||||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Qualitymakes sense why to do this as to wrap this around the existing dict, but I am wary of sharing the underlying storage this way.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIt's very intentional, that the registry shares the underlying storage: For a transition period, the registry and the cmap functions will coexists. Due to API quirks in the functions, it's better if both can directly work on the underlying storage and not one API calling the orther. If you only have concerns with the constructor accepting a prebuilt mapping, we can change it to creating an empty registry by default and have a private ColormapRegistry._from_dict() that we use to inject the existing dict.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI would be happy warning in the init docstring saying we keep a reference to the input dict. It makes total sense why you are doing it this way, just set off alarm bells in my head (we have had some cases at BNL where we did not mean to do this and ended up with hard-to-debug action-at-a-distance bugs!).
Sorry, something went wrong.
All reactions
|
||||||||
|
|
||||||||
| def __getitem__(self, item): | ||||||||
| try: | ||||||||
| return self._cmaps[item].copy() | ||||||||
| except KeyError: | ||||||||
| raise KeyError(f"{item!r} is not a known colormap name") | ||||||||
|
|
||||||||
| def __iter__(self): | ||||||||
| return iter(self._cmaps) | ||||||||
|
|
||||||||
| def __len__(self): | ||||||||
| return len(self._cmaps) | ||||||||
|
|
||||||||
| def __str__(self): | ||||||||
| return ('ColormapRegistry; available colormaps:\n' + | ||||||||
| ', '.join(f"'{name}'" for name in self)) | ||||||||
|
|
||||||||
| def register(self, cmap, *, name=None, force=False): | ||||||||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI think we need an deregister as well? with force you can over-write an existing colormap, but I still think we will want a way to remove a key. I do not think we want to promote this to a MutableMapping and support the full set of del / pop / clear. The act of adding and removing color maps is a different activity than the act of getting a colormap out of the registry.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI agree that some sort of deregister should be there at some point. Details would need to be discussed, e.g. if you can deregister built-in cmaps (I think that should not be possible these are reseverd names with fixed meaning and no public API should change them). Anyway, we currently don't have a deregister function, so there is no hurry with adding that new feature in the initial version of the registry.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWe have unregister_cmap which went out in 3.4 via #15127 matplotlib/lib/matplotlib/cm.py Lines 197 to 199 in 1761822
Sorry, something went wrong.
All reactions
|
||||||||
| """ | ||||||||
| Register a new colormap. | ||||||||
|
|
||||||||
| The colormap name can then be used as a string argument to any ``cmap`` | ||||||||
| parameter in Matplotlib. It is also available in ``pyplot.get_cmap``. | ||||||||
|
|
||||||||
| The colormap registry stores a copy of the given colormap, so that | ||||||||
| future changes to the original colormap instance do not affect the | ||||||||
| registered colormap. Think of this as the registry taking a snapshot | ||||||||
| of the colormap at registration. | ||||||||
|
|
||||||||
| Parameters | ||||||||
| ---------- | ||||||||
| cmap : matplotlib.colors.Colormap | ||||||||
| The colormap to register. | ||||||||
|
|
||||||||
| name : str, optional | ||||||||
| The name for the colormap. If not given, ``cmap.name`` is used. | ||||||||
|
|
||||||||
| force: bool, default: False | ||||||||
| If False, a ValueError is raised if trying to overwrite an already | ||||||||
| registered name. True supports overwriting registered colormaps | ||||||||
| other than the builtin colormaps. | ||||||||
| """ | ||||||||
| name = name or cmap.name | ||||||||
| if name in self and not force: | ||||||||
| raise ValueError( | ||||||||
| f'A colormap named "{name}" is already registered.') | ||||||||
| register_cmap(name, cmap.copy()) | ||||||||
|
|
||||||||
|
|
||||||||
| _cmap_registry = _gen_cmap_registry() | ||||||||
| globals().update(_cmap_registry) | ||||||||
| # This is no longer considered public API | ||||||||
| cmap_d = _DeprecatedCmapDictWrapper(_cmap_registry) | ||||||||
| __builtin_cmaps = tuple(_cmap_registry) | ||||||||
|
|
||||||||
| # Continue with definitions ... | ||||||||
| # public acces to the colormaps should be via `matplotlib.colormaps`. For now, | ||||||||
| # we still create the registry here, but that should stay an implementation | ||||||||
| # detail. | ||||||||
| _colormaps = ColormapRegistry(_cmap_registry) | ||||||||
|
|
||||||||
|
|
||||||||
| def register_cmap(name=None, cmap=None, *, override_builtin=False): | ||||||||
| Expand Down | ||||||||
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityCould we handle this in the module level __getattr__ now that we have than in place?
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.