diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index c763d8cb7a83..71360ad1c612 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -234,15 +234,6 @@ def _has_alpha_channel(c): return not isinstance(c, str) and len(c) == 4 -def _check_color_like(**kwargs): - """ - For each *key, value* pair in *kwargs*, check that *value* is color-like. - """ - for k, v in kwargs.items(): - if not is_color_like(v): - raise ValueError(f"{v!r} is not a valid value for {k}") - - def same_color(c1, c2): """ Return whether the colors *c1* and *c2* are the same. @@ -262,7 +253,7 @@ def same_color(c1, c2): return c1.shape == c2.shape and (c1 == c2).all() -def to_rgba(c, alpha=None): +def to_rgba(c, alpha=None, errname=None): """ Convert *c* to an RGBA color. @@ -296,15 +287,16 @@ def to_rgba(c, alpha=None): except (KeyError, TypeError): # Not in cache, or unhashable. rgba = None if rgba is None: # Suppress exception chaining of cache lookup failure. - rgba = _to_rgba_no_colorcycle(c, alpha) + rgba = _to_rgba_no_colorcycle(c, alpha, errname) try: _colors_full_map.cache[c, alpha] = rgba except TypeError: pass + return rgba -def _to_rgba_no_colorcycle(c, alpha=None): +def _to_rgba_no_colorcycle(c, alpha=None, errname=None): """ Convert *c* to an RGBA color, with no support for color-cycle syntax. @@ -368,23 +360,27 @@ def _to_rgba_no_colorcycle(c, alpha=None): else: if not (0 <= c <= 1): raise ValueError( - f"Invalid string grayscale value {orig_c!r}. " + f"Invalid string grayscale value {orig_c!r} " + f'{" is not a valid value for " + errname if errname else ""}.' f"Value must be within 0-1 range") return c, c, c, alpha if alpha is not None else 1. - raise ValueError(f"Invalid RGBA argument: {orig_c!r}") + raise ValueError(f'Invalid RGBA argument {orig_c!r}' + f'{" is not a valid value for " + errname if errname else ""}') # turn 2-D array into 1-D array if isinstance(c, np.ndarray): if c.ndim == 2 and c.shape[0] == 1: c = c.reshape(-1) # tuple color. if not np.iterable(c): - raise ValueError(f"Invalid RGBA argument: {orig_c!r}") + raise ValueError(f"Invalid RGBA argument {orig_c!r}" + f'{" is not a valid value for " + errname if errname else ""}') if len(c) not in [3, 4]: raise ValueError("RGBA sequence should have length 3 or 4") if not all(isinstance(x, Number) for x in c): # Checks that don't work: `map(float, ...)`, `np.array(..., float)` and # `np.array(...).astype(float)` would all convert "0.5" to 0.5. - raise ValueError(f"Invalid RGBA argument: {orig_c!r}") + raise ValueError(f"Invalid RGBA argument {orig_c!r}" + f'{" is not a valid value for " + errname if errname else ""}') # Return a tuple to prevent the cached value from being modified. c = tuple(map(float, c)) if len(c) == 3 and alpha is None: @@ -396,7 +392,7 @@ def _to_rgba_no_colorcycle(c, alpha=None): return c -def to_rgba_array(c, alpha=None): +def to_rgba_array(c, alpha=None, errname=None): """ Convert *c* to a (n, 4) array of RGBA colors. @@ -468,7 +464,8 @@ def to_rgba_array(c, alpha=None): pass if isinstance(c, str): - raise ValueError(f"{c!r} is not a valid color value.") + raise ValueError(f"{c!r} is not a valid " + f'{"value for " + errname if errname else "color value."}') if len(c) == 0: return np.zeros((0, 4), float) diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index ef92b975b21d..527e35cf2856 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -1056,7 +1056,7 @@ def set_color(self, color): ---------- color : color """ - mcolors._check_color_like(color=color) + _ = mcolors.to_rgba(color, errname="color") self._color = color self.stale = True @@ -1114,7 +1114,7 @@ def set_gapcolor(self, gapcolor): unfilled. """ if gapcolor is not None: - mcolors._check_color_like(color=gapcolor) + _ = mcolors.to_rgba(gapcolor, errname="gapcolor") self._gapcolor = gapcolor self.stale = True diff --git a/lib/matplotlib/text.py b/lib/matplotlib/text.py index 0f874ba33db7..e55b1163d406 100644 --- a/lib/matplotlib/text.py +++ b/lib/matplotlib/text.py @@ -11,7 +11,7 @@ import numpy as np import matplotlib as mpl -from . import _api, artist, cbook, _docstring +from . import _api, artist, cbook, colors as mcolors, _docstring from .artist import Artist from .font_manager import FontProperties from .patches import FancyArrowPatch, FancyBboxPatch, Rectangle @@ -993,7 +993,7 @@ def set_color(self, color): # "auto" is only supported by axisartist, but we can just let it error # out at draw time for simplicity. if not cbook._str_equal(color, "auto"): - mpl.colors._check_color_like(color=color) + _ = mcolors.to_rgba(color, errname="color") self._color = color self.stale = True diff --git a/lib/matplotlib/widgets.py b/lib/matplotlib/widgets.py index 9668c0233d9f..4bb2faa36348 100644 --- a/lib/matplotlib/widgets.py +++ b/lib/matplotlib/widgets.py @@ -1776,7 +1776,7 @@ def activecolor(self): @activecolor.setter def activecolor(self, activecolor): - colors._check_color_like(activecolor=activecolor) + _ = colors.to_rgba(activecolor, errname="activecolor") self._activecolor = activecolor self.set_radio_props({'facecolor': activecolor}) # Make sure the deprecated version is updated. diff --git a/lib/mpl_toolkits/axisartist/axis_artist.py b/lib/mpl_toolkits/axisartist/axis_artist.py index 74df999ef24e..aa746bfe6fd8 100644 --- a/lib/mpl_toolkits/axisartist/axis_artist.py +++ b/lib/mpl_toolkits/axisartist/axis_artist.py @@ -139,7 +139,7 @@ def set_color(self, color): # docstring inherited # Unlike the base Line2D.set_color, this also supports "auto". if not cbook._str_equal(color, "auto"): - mcolors._check_color_like(color=color) + _ = mcolors.to_rgba(color, errname="color") self._color = color self.stale = True