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

Further simplify colormap reversal. #14679

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 1 commit into from
Jul 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions 7 doc/api/next_api_changes/2019-07-03-AL.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Deprecations
````````````

``cm.revcmap`` is deprecated. Use `.Colormap.reversed` to reverse a colormap.

``cm.datad`` no longer contains entries for reversed colormaps in their
"unconverted" form.
77 changes: 24 additions & 53 deletions 77 lib/matplotlib/cm.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

:doc:`/tutorials/colors/colormapnorms` for more details about data
normalization.


"""

import functools
Expand All @@ -29,17 +27,11 @@
from matplotlib._cm_listed import cmaps as cmaps_listed


cmap_d = {}


# reverse all the colormaps.
# reversed colormaps have '_r' appended to the name.


def _reverser(f, x): # Toplevel helper for revcmap ensuring cmap picklability.
return f(1 - x)
def _reverser(f, x): # Deprecated, remove this at the same time as revcmap.
return f(1 - x) # Toplevel helper for revcmap ensuring cmap picklability.


@cbook.deprecated("3.2", alternative="Colormap.reversed()")
def revcmap(data):
"""Can only handle specification *data* in dictionary format."""
data_r = {}
Expand All @@ -54,51 +46,30 @@ def revcmap(data):
return data_r


def _reverse_cmap_spec(spec):
"""Reverses cmap specification *spec*, can handle both dict and tuple
type specs."""

if 'listed' in spec:
return {'listed': spec['listed'][::-1]}

if 'red' in spec:
return revcmap(spec)
else:
revspec = list(reversed(spec))
if len(revspec[0]) == 2: # e.g., (1, (1.0, 0.0, 1.0))
revspec = [(1.0 - a, b) for a, b in revspec]
return revspec


def _generate_cmap(name, lutsize):
"""Generates the requested cmap from its *name*. The lut size is
*lutsize*."""

spec = datad[name]

# Generate the colormap object.
if 'red' in spec:
return colors.LinearSegmentedColormap(name, spec, lutsize)
elif 'listed' in spec:
return colors.ListedColormap(spec['listed'], name)
else:
return colors.LinearSegmentedColormap.from_list(name, spec, lutsize)


LUTSIZE = mpl.rcParams['image.lut']

# Generate the reversed specifications (all at once, to avoid
# modify-when-iterating).
datad.update({cmapname + '_r': _reverse_cmap_spec(spec)
for cmapname, spec in datad.items()})

# Precache the cmaps with ``lutsize = LUTSIZE``.
# Also add the reversed ones added in the section above:
for cmapname in datad:
cmap_d[cmapname] = _generate_cmap(cmapname, LUTSIZE)

cmap_d.update(cmaps_listed)

def _gen_cmap_d():
"""
Generate a dict mapping standard colormap names to standard colormaps, as
well as the reversed colormaps.
"""
cmap_d = {**cmaps_listed}
anntzer marked this conversation as resolved.
Show resolved Hide resolved
for name, spec in datad.items():
cmap_d[name] = ( # Precache the cmaps at a fixed lutsize..
colors.LinearSegmentedColormap(name, spec, LUTSIZE)
if 'red' in spec else
colors.ListedColormap(spec['listed'], name)
if 'listed' in spec else
colors.LinearSegmentedColormap.from_list(name, spec, LUTSIZE))
# Generate reversed cmaps.
for cmap in list(cmap_d.values()):
rmap = cmap.reversed()
cmap_d[rmap.name] = rmap
return cmap_d


cmap_d = _gen_cmap_d()
locals().update(cmap_d)


Expand Down
16 changes: 9 additions & 7 deletions 16 lib/matplotlib/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"""

from collections.abc import Sized
import functools
import itertools
import re

Expand Down Expand Up @@ -795,6 +796,11 @@ def _resample(self, lutsize):
"""
return LinearSegmentedColormap(self.name, self._segmentdata, lutsize)

# Helper ensuring picklability of the reversed cmap.
@staticmethod
def _reverser(func, x):
return func(1 - x)

def reversed(self, name=None):
"""
Make a reversed instance of the Colormap.
Expand All @@ -813,13 +819,9 @@ def reversed(self, name=None):
if name is None:
name = self.name + "_r"

# Function factory needed to deal with 'late binding' issue.
def factory(dat):
def func_r(x):
return dat(1.0 - x)
return func_r

data_r = {key: (factory(data) if callable(data) else
# Using a partial object keeps the cmap picklable.
data_r = {key: (functools.partial(self._reverser, data)
if callable(data) else
[(1.0 - x, y1, y0) for x, y0, y1 in reversed(data)])
for key, data in self._segmentdata.items()}

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