Skip to content

Commit 46ea8f0

Browse files
authored
Merge pull request matplotlib#29052 from 3j14/fix-colors-from_list
FIX: Checks for (value, color) tuples in LinearSegmentedColormap.from_list
2 parents ae47a6e + d9b8020 commit 46ea8f0

File tree

2 files changed

+52
-8
lines changed

2 files changed

+52
-8
lines changed

lib/matplotlib/colors.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"""
4141

4242
import base64
43-
from collections.abc import Sized, Sequence, Mapping
43+
from collections.abc import Sequence, Mapping
4444
import functools
4545
import importlib
4646
import inspect
@@ -1180,7 +1180,8 @@ def from_list(name, colors, N=256, gamma=1.0, *, bad=None, under=None, over=None
11801180
range :math:`[0, 1]`; i.e. 0 maps to ``colors[0]`` and 1 maps to
11811181
``colors[-1]``.
11821182
If (value, color) pairs are given, the mapping is from *value*
1183-
to *color*. This can be used to divide the range unevenly.
1183+
to *color*. This can be used to divide the range unevenly. The
1184+
values must increase monotonically from 0 to 1.
11841185
N : int
11851186
The number of RGB quantization levels.
11861187
gamma : float
@@ -1195,14 +1196,26 @@ def from_list(name, colors, N=256, gamma=1.0, *, bad=None, under=None, over=None
11951196
if not np.iterable(colors):
11961197
raise ValueError('colors must be iterable')
11971198

1198-
if (isinstance(colors[0], Sized) and len(colors[0]) == 2
1199-
and not isinstance(colors[0], str)):
1200-
# List of value, color pairs
1201-
vals, colors = zip(*colors)
1202-
else:
1199+
try:
1200+
# Assume the passed colors are a list of colors
1201+
# and not a (value, color) tuple.
1202+
r, g, b, a = to_rgba_array(colors).T
12031203
vals = np.linspace(0, 1, len(colors))
1204+
except Exception as e:
1205+
# Assume the passed values are a list of
1206+
# (value, color) tuples.
1207+
try:
1208+
_vals, _colors = itertools.zip_longest(*colors)
1209+
except Exception as e2:
1210+
raise e2 from e
1211+
vals = np.asarray(_vals)
1212+
if np.min(vals) < 0 or np.max(vals) > 1 or np.any(np.diff(vals) <= 0):
1213+
raise ValueError(
1214+
"the values passed in the (value, color) pairs "
1215+
"must increase monotonically from 0 to 1."
1216+
)
1217+
r, g, b, a = to_rgba_array(_colors).T
12041218

1205-
r, g, b, a = to_rgba_array(colors).T
12061219
cdict = {
12071220
"red": np.column_stack([vals, r, r]),
12081221
"green": np.column_stack([vals, g, g]),

lib/matplotlib/tests/test_colors.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,3 +1780,34 @@ def test_colorizer_vmin_vmax():
17801780
assert ca.vmax == 3.0
17811781
assert ca.norm.vmin == 1.0
17821782
assert ca.norm.vmax == 3.0
1783+
1784+
1785+
def test_LinearSegmentedColormap_from_list_color_alpha_tuple():
1786+
"""
1787+
GitHub issue #29042: A bug in 'from_list' causes an error
1788+
when passing a tuple (str, float) where the string is a
1789+
color name or grayscale value and float is an alpha value.
1790+
"""
1791+
colors = [("red", 0.3), ("0.42", 0.1), "green"]
1792+
cmap = mcolors.LinearSegmentedColormap.from_list("lsc", colors, N=3)
1793+
assert_array_almost_equal(cmap([.0, 0.5, 1.]), to_rgba_array(colors))
1794+
1795+
1796+
@pytest.mark.parametrize("colors",
1797+
[[(0.42, "blue"), (.1, .1, .1, .1)],
1798+
["blue", (0.42, "red")],
1799+
["blue", (.1, .1, .1, .1), ("red", 2)],
1800+
[(0, "red"), (1.1, "blue")],
1801+
[(0.52, "red"), (0.42, "blue")]])
1802+
def test_LinearSegmentedColormap_from_list_invalid_inputs(colors):
1803+
with pytest.raises(ValueError):
1804+
mcolors.LinearSegmentedColormap.from_list("lsc", colors)
1805+
1806+
1807+
def test_LinearSegmentedColormap_from_list_value_color_tuple():
1808+
value_color_tuples = [(0, "red"), (0.6, "blue"), (1, "green")]
1809+
cmap = mcolors.LinearSegmentedColormap.from_list("lsc", value_color_tuples, N=11)
1810+
assert_array_almost_equal(
1811+
cmap([value for value, _ in value_color_tuples]),
1812+
to_rgba_array([color for _, color in value_color_tuples]),
1813+
)

0 commit comments

Comments
 (0)