GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — [Bug]: Setting exactly 2 colors with tuple in `plot` method gives confusing error · Issue #28434 · matplotlib/matplotlib

[Bug]: Setting exactly 2 colors with tuple in plot method gives confusing error #28434

New issue
Copy link
New issue
Copy link
Closed
#28436
Closed
[Bug]: Setting exactly 2 colors with tuple in plot method gives confusing error#28434
#28436
Copy link
Labels
status: confirmed bug
Milestone
v3.9.1

Description

@miles-1
miles-1
opened on Jun 21, 2024
Issue body actions

Bug summary

If one attempts to set the color parameter to a tuple of length 2, a nonsense error message is returned.

Code for reproduction

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.array([np.sin(x), np.cos(x)]).T

plt.plot(x, y, label=("sin(x)", "cos(x)")) # works
plt.plot(x, y, label=("sin(x)", "cos(x)"), color=("red", "blue")) # causes strange error
plt.legend()
plt.show()

Actual outcome

Traceback (most recent call last):
File "/Users/miles/Desktop/thing.py", line 8, in
plt.plot(x, y, label=("sin(x)", "cos(x)"), color=("red", "blue")) # causes error
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/pyplot.py", line 3708, in plot
return gca().plot(
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/axes/_axes.py", line 1779, in plot
lines = [*self._get_lines(self, *args, data=data, **kwargs)]
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/axes/_base.py", line 296, in call
yield from self._plot_args(
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/axes/_base.py", line 534, in _plot_args
return [l[0] for l in result]
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/axes/_base.py", line 534, in
return [l[0] for l in result]
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/axes/_base.py", line 527, in
result = (make_artist(axes, x[:, j % ncx], y[:, j % ncy], kw,
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/axes/_base.py", line 335, in _makeline
seg = mlines.Line2D(x, y, **kw)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/lines.py", line 376, in init
self.set_color(color)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/lines.py", line 1066, in set_color
mcolors._check_color_like(color=color)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/colors.py", line 245, in _check_color_like
if not is_color_like(v):
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/colors.py", line 227, in is_color_like
to_rgba(c)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/colors.py", line 309, in to_rgba
rgba = _to_rgba_no_colorcycle(c, alpha)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/matplotlib/colors.py", line 334, in _to_rgba_no_colorcycle
if alpha is not None and not 0 <= alpha <= 1:
TypeError: '<=' not supported between instances of 'int' and 'str'

Expected outcome

Either: (1) works as expected as passing a tuple to label does, or, if this won't be supported, (2) a more sensical error message is returned, like if ["red", "blue"] were passed.

Additional information

This difficult-to-interpret error seems to be caused by the if statement of line 328 in _to_rgba_no_colorcycle in colors.py, which says if isinstance(c, tuple) and len(c) == 2. If I comment out this if statement, then the error message gives the normal ValueError: ('red', 'blue') is not a valid value for color... message. Of course, it would be great if multiple colors were supported here, but I understand if there is a bigger reason why it is not supported.

Operating system

macOS 14.4.1

Matplotlib Version

3.9.0

Matplotlib Backend

macosx

Python version

3.9.6

Jupyter version

No response

Installation

pip

Activity

  1. ksunden commented on Jun 21, 2024

    @ksunden
    ksunden
    on Jun 21, 2024
    Member
    More actions

    This is a result of the (color, alpha) version of specifying colors that was introduced in 3.8.0

    That is why it is specifically tuples (not lists) and specifically length 2...

    My gut reaction is that the new color specifier is useful enough and the workaround (casting to list) is easy enough that I'm inclined towards keeping current behavior...

    On the other hand, it may be reasonable to narrow the condition further to "is the second entry in a length 2 tuple a number"... and if it is not, treat it as a standard sequence of 2 colors instead...

    As long as numbers are not valid color specifiers, this would differentiate the cases. I believe that is the case (though string floating point values are valid color specifiers for shades of gray...). Because if a number were a valid color specifier, then this would be an ambiguous case.

  2. rcomer commented on Jun 21, 2024

    @rcomer
    rcomer
    on Jun 21, 2024
    Member
    More actions

    Just catching the TypeError within is_color_like makes the error consistent with the list case

    diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py
    index c4e5987fdf..f6e78dc3e4 100644
    --- a/lib/matplotlib/colors.py
    +++ b/lib/matplotlib/colors.py
    @@ -225,7 +225,7 @@ def is_color_like(c):
             return True
         try:
             to_rgba(c)
    -    except ValueError:
    +    except (ValueError, TypeError):
             return False
         else:
             return True
    
    ValueError: ('red', 'blue') is not a valid value for color: supported inputs are (r, g, b) and (r, g, b, a) 0-1 float tuples; '#rrggbb', '#rrggbbaa', '#rgb', '#rgba' strings; named color strings; string reprs of 0-1 floats for grayscale values; 'C0', 'C1', ... strings for colors of the color cycle; and pairs combining one of the above with an alpha value
    
    
  3. rcomer commented on Jun 21, 2024

    @rcomer
    rcomer
    on Jun 21, 2024
    Member
    More actions

    Note there is no issue with functions that do take a color sequence

    plt.scatter([1, 2], [4, 5], c=("red", "blue"))

    image

  4. story645 commented on Jun 21, 2024

    @story645
    story645
    on Jun 21, 2024
    Member
    More actions

    Note there is no issue with functions that do take a color sequence

    Do we want to allow this function to take a color sequence? It would be in line w/ the other PRs that are vectorizing inputs.

  5. rcomer commented on Jun 21, 2024

    @rcomer
    rcomer
    on Jun 21, 2024
    Member
    More actions

    It does seem odd that by default you get 2 colors but you cannot specify 2 colors.

    Reacted by hannah and miles
  6. timhoffm commented on Jun 22, 2024

    @timhoffm
    timhoffm
    on Jun 22, 2024
    Member
    More actions

    The _is_color_like change proposed by @rcomer above should be applied no matter what.

    I'm a bit hesitant on supporting sequences for color. If we do that, we'd have to expand to all parameters consistently. Note in particular that some parameters use sequences as single-value represenations already, e.g. colors and linestyles, so detection of sequence-of-parameters is non-trivial. It's not completely unreasonable to support seqnce-of-parameters, but adds significant complexity to an already very complex function. If somebody implements this, I'd like to see an as-clean-as possible implementation.

    When adding label sequences, we've explicitly done that as an exception without the promise to support sequences on all parameters. The argument is that all other parameters can be addressed through the property cycle, i.e. can be configured up-front to a multiple-data plot. That's not possible for labels. See #16178 (comment).

    Reacted by Ruth Comer, miles and Jody Klymak
  7. rcomer
    added
    status: confirmed bug
    on Jun 22, 2024
  8. jklymak commented on Jun 22, 2024

    @jklymak
    jklymak
    on Jun 22, 2024
    Member
    More actions

    I think that in general the idea of two d conveniences for one d plotting functions is more trouble than it is worth and leads to an inconsistent API. In fact, I'd argue that allowing lists of labels was a bad idea to start with. If people need to style individual columns of a data set differently, and they don't want to deal with our cycler, they can use a trivial for-loop. (I see I am repeating myself from #16178)

    Of course I do agree that the error message is terrible here.

  9. story645
    closed this as completedin #28436on Jun 23, 2024
  10. rcomer
    added this to the v3.9.1 milestone on Jun 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: confirmed bug

    Type

    No type

    Projects

    No projects

      Milestone

      • v3.9.1

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402520 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.