8000 Make ListedColormap.monochrome a property · matplotlib/matplotlib@5827742 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5827742

Browse files
committed
Make ListedColormap.monochrome a property
The calculated property replaces the attribute *monochome*, which was manually set on `__init__`, but was not correctly set for all possible inputs. This property ensures consistency and simplifies initialization at the cost of some computation overhead to determine whether the colormap is monochrome. The computation cost is bearable (even without caching), because it's only used in `ContourSet._process_colors`. It's a separate discussion whether we need this property on colormaps at all (at least as public API). Usually, colormaps are not monochrome and monochrome colormaps are a very special edge case used in contours only. We may eventually deprecate it, but since it is currently public API, let's leave it for now. There's also a technical API incompatibility in that users cannot set the attribute anymore, but I'd argue that that has never been intended and there's no practical use-case, so I refrain from the extra hassle of allowing setting this property.
1 parent ca39d41 commit 5827742

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

lib/matplotlib/colors.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,17 +1191,13 @@ class ListedColormap(Colormap):
11911191
the list will be extended by repetition.
11921192
"""
11931193
def __init__(self, colors, name='from_list', N=None):
1194-
self.monochrome = False # Are all colors identical? (for contour.py)
11951194
if N is None:
11961195
self.colors = colors
11971196
N = len(colors)
11981197
else:
11991198
if isinstance(colors, str):
12001199
self.colors = [colors] * N
1201-
self.monochrome = True
12021200
elif np.iterable(colors):
1203-
if len(colors) == 1:
1204-
self.monochrome = True
12051201
self.colors = list(
12061202
itertools.islice(itertools.cycle(colors), N))
12071203
else:
@@ -1211,7 +1207,6 @@ def __init__(self, colors, name='from_list', N=None):
12111207
pass
12121208
else:
12131209
self.colors = [gray] * N
1214-
self.monochrome = True
12151210
super().__init__(name, N)
1216121 10000 1

12171212
def _init(self):
@@ -1220,6 +1215,24 @@ def _init(self):
12201215
self._isinit = True
12211216
self._set_extremes()
12221217

1218+
@property
1219+
def monochrome(self):
1220+
"""Return whether all colors in the colormap are identical."""
1221+
# Replacement for the attribute *monochrome*. This ensures a consistent
1222+
# response independent of the way the ListedColormap was created, which
1223+
# was not the case for the manually set attribute.
1224+
#
1225+
# TODO: It's a separate discussion whether we need this property on
1226+
# colormaps at all (at least as public API). It's a very special edge
1227+
# case and we only use it for contours internally.
1228+
if not self._isinit:
1229+
self._init()
1230+
1231+
N = len(self._lut) - 3 # disregard over / under / bad
1232+
if N <= 1:
1233+
return True
1234+
return np.all(self._lut[0] == self._lut[1:N])
1235+
12231236
def resampled(self, lutsize):
12241237
"""Return a new colormap with *lutsize* entries."""
12251238
colors = self(np.linspace(0, 1, lutsize))

lib/matplotlib/tests/test_colors.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ def test_resampled():
7474
assert_array_almost_equal(lc(np.nan), lc3(np.nan))
7575

7676

77+
def test_monochrome():
78+
assert mcolors.ListedColormap(["red"]).monochrome
79+
assert mcolors.ListedColormap(["red"] * 5).monochrome
80+
assert not mcolors.ListedColormap(["red", "green"]).monochrome
81+
82+
7783
def test_colormaps_get_cmap():
7884
cr = mpl.colormaps
7985

0 commit comments

Comments
 (0)
0