From dbc205d80642999933926805097b26028976d2bf Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Wed, 10 Apr 2019 01:21:53 +0200 Subject: [PATCH] Fix string numbers in to_rgba() and is_color_like() --- doc/api/next_api_changes/2019-04-13-TH.rst | 7 +++++++ lib/matplotlib/colors.py | 12 +++++++++--- lib/matplotlib/tests/test_colors.py | 18 ++++++++++++------ 3 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 doc/api/next_api_changes/2019-04-13-TH.rst diff --git a/doc/api/next_api_changes/2019-04-13-TH.rst b/doc/api/next_api_changes/2019-04-13-TH.rst new file mode 100644 index 000000000000..e8c8176cead3 --- /dev/null +++ b/doc/api/next_api_changes/2019-04-13-TH.rst @@ -0,0 +1,7 @@ +API changes +``````````` + +`matplotlib.color.is_colorlike()` used to return True for all string +representations of floats. However, only those with values in 0-1 are valid +colors (representing grayscale values). ``is_colorlike()`` now returns False +for string representations of floats outside 0-1. diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 08916606a393..2a9c7092c631 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -225,17 +225,23 @@ def _to_rgba_no_colorcycle(c, alpha=None): return tuple(color) # string gray. try: - return (float(c),) * 3 + (alpha if alpha is not None else 1.,) + c = float(c) except ValueError: pass - raise ValueError("Invalid RGBA argument: {!r}".format(orig_c)) + else: + if not (0 <= c <= 1): + raise ValueError( + f"Invalid string grayscale value {orig_c!r}. " + 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}") # tuple color. c = np.array(c) if not np.can_cast(c.dtype, float, "same_kind") or c.ndim != 1: # Test the dtype explicitly as `map(float, ...)`, `np.array(..., # float)` and `np.array(...).astype(float)` all convert "0.5" to 0.5. # Test dimensionality to reject single floats. - raise ValueError("Invalid RGBA argument: {!r}".format(orig_c)) + raise ValueError(f"Invalid RGBA argument: {orig_c!r}") # Return a tuple to prevent the cached value from being modified. c = tuple(c.astype(float)) if len(c) not in [3, 4]: diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index b08721407219..19fabbfdb551 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -471,12 +471,6 @@ def test_autoscale_masked(): plt.draw() -def test_colors_no_float(): - # Gray must be a string to distinguish 3-4 grays from RGB or RGBA. - with pytest.raises(ValueError): - mcolors.to_rgba(0.4) - - @image_comparison(baseline_images=['light_source_shading_topo'], extensions=['png']) def test_light_source_topo_surface(): @@ -756,6 +750,18 @@ def test_conversions(): hex_color +def test_failed_conversions(): + with pytest.raises(ValueError): + mcolors.to_rgba('5') + with pytest.raises(ValueError): + mcolors.to_rgba('-1') + with pytest.raises(ValueError): + mcolors.to_rgba('nan') + with pytest.raises(ValueError): + # Gray must be a string to distinguish 3-4 grays from RGB or RGBA. + mcolors.to_rgba(0.4) + + def test_grey_gray(): color_mapping = mcolors._colors_full_map for k in color_mapping.keys():