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

Commit 8c587e5

Browse filesBrowse files
authored
Merge pull request #14679 from anntzer/revcmap
Further simplify colormap reversal.
2 parents 8d82733 + c2032ab commit 8c587e5
Copy full SHA for 8c587e5

File tree

Expand file treeCollapse file tree

3 files changed

+40
-60
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+40
-60
lines changed
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Deprecations
2+
````````````
3+
4+
``cm.revcmap`` is deprecated. Use `.Colormap.reversed` to reverse a colormap.
5+
6+
``cm.datad`` no longer contains entries for reversed colormaps in their
7+
"unconverted" form.

‎lib/matplotlib/cm.py

Copy file name to clipboardExpand all lines: lib/matplotlib/cm.py
+24-53Lines changed: 24 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
1414
:doc:`/tutorials/colors/colormapnorms` for more details about data
1515
normalization.
16-
17-
1816
"""
1917

2018
import functools
@@ -29,17 +27,11 @@
2927
from matplotlib._cm_listed import cmaps as cmaps_listed
3028

3129

32-
cmap_d = {}
33-
34-
35-
# reverse all the colormaps.
36-
# reversed colormaps have '_r' appended to the name.
37-
38-
39-
def _reverser(f, x): # Toplevel helper for revcmap ensuring cmap picklability.
40-
return f(1 - x)
30+
def _reverser(f, x): # Deprecated, remove this at the same time as revcmap.
31+
return f(1 - x) # Toplevel helper for revcmap ensuring cmap picklability.
4132

4233

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

5648

57-
def _reverse_cmap_spec(spec):
58-
"""Reverses cmap specification *spec*, can handle both dict and tuple
59-
type specs."""
60-
61-
if 'listed' in spec:
62-
return {'listed': spec['listed'][::-1]}
63-
64-
if 'red' in spec:
65-
return revcmap(spec)
66-
else:
67-
revspec = list(reversed(spec))
68-
if len(revspec[0]) == 2: # e.g., (1, (1.0, 0.0, 1.0))
69-
revspec = [(1.0 - a, b) for a, b in revspec]
70-
return revspec
71-
72-
73-
def _generate_cmap(name, lutsize):
74-
"""Generates the requested cmap from its *name*. The lut size is
75-
*lutsize*."""
76-
77-
spec = datad[name]
78-
79-
# Generate the colormap object.
80-
if 'red' in spec:
81-
return colors.LinearSegmentedColormap(name, spec, lutsize)
82-
elif 'listed' in spec:
83-
return colors.ListedColormap(spec['listed'], name)
84-
else:
85-
return colors.LinearSegmentedColormap.from_list(name, spec, lutsize)
86-
87-
8849
LUTSIZE = mpl.rcParams['image.lut']
8950

90-
# Generate the reversed specifications (all at once, to avoid
91-
# modify-when-iterating).
92-
datad.update({cmapname + '_r': _reverse_cmap_spec(spec)
93-
for cmapname, spec in datad.items()})
94-
95-
# Precache the cmaps with ``lutsize = LUTSIZE``.
96-
# Also add the reversed ones added in the section above:
97-
for cmapname in datad:
98-
cmap_d[cmapname] = _generate_cmap(cmapname, LUTSIZE)
99-
100-
cmap_d.update(cmaps_listed)
10151

52+
def _gen_cmap_d():
53+
"""
54+
Generate a dict mapping standard colormap names to standard colormaps, as
55+
well as the reversed colormaps.
56+
"""
57+
cmap_d = {**cmaps_listed}
58+
for name, spec in datad.items():
59+
cmap_d[name] = ( # Precache the cmaps at a fixed lutsize..
60+
colors.LinearSegmentedColormap(name, spec, LUTSIZE)
61+
if 'red' in spec else
62+
colors.ListedColormap(spec['listed'], name)
63+
if 'listed' in spec else
64+
colors.LinearSegmentedColormap.from_list(name, spec, LUTSIZE))
65+
# Generate reversed cmaps.
66+
for cmap in list(cmap_d.values()):
67+
rmap = cmap.reversed()
68+
cmap_d[rmap.name] = rmap
69+
return cmap_d
70+
71+
72+
cmap_d = _gen_cmap_d()
10273
locals().update(cmap_d)
10374

10475

‎lib/matplotlib/colors.py

Copy file name to clipboardExpand all lines: lib/matplotlib/colors.py
+9-7Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"""
6161

6262
from collections.abc import Sized
63+
import functools
6364
import itertools
6465
import re
6566

@@ -795,6 +796,11 @@ def _resample(self, lutsize):
795796
"""
796797
return LinearSegmentedColormap(self.name, self._segmentdata, lutsize)
797798

799+
# Helper ensuring picklability of the reversed cmap.
800+
@staticmethod
801+
def _reverser(func, x):
802+
return func(1 - x)
803+
798804
def reversed(self, name=None):
799805
"""
800806
Make a reversed instance of the Colormap.
@@ -813,13 +819,9 @@ def reversed(self, name=None):
813819
if name is None:
814820
name = self.name + "_r"
815821

816-
# Function factory needed to deal with 'late binding' issue.
817-
def factory(dat):
818-
def func_r(x):
819-
return dat(1.0 - x)
820-
return func_r
821-
822-
data_r = {key: (factory(data) if callable(data) else
822+
# Using a partial object keeps the cmap picklable.
823+
data_r = {key: (functools.partial(self._reverser, data)
824+
if callable(data) else
823825
[(1.0 - x, y1, y0) for x, y0, y1 in reversed(data)])
824826
for key, data in self._segmentdata.items()}
825827

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.