Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when color value is None #4192

Closed
kyleam opened this issue Mar 4, 2015 · 8 comments
Closed

Error when color value is None #4192

kyleam opened this issue Mar 4, 2015 · 8 comments
Milestone

Comments

@kyleam
Copy link

kyleam commented Mar 4, 2015

Commit d58a84a changed validate_colors so that value in rcParams is None rather than "None". However, in some cases, it seems that a string is still expected downstream.

For example,

import matplotlib.pyplot as plt
import matplotlib as mpl

mpl.rcParams['patch.edgecolor'] = None

plt.plot(list(range(5)))

results in

Traceback (most recent call last):
  File "[...]/matplotlib/lib/matplotlib/colors.py", line 322, in to_rgb
    'cannot convert argument to rgb sequence')
ValueError: cannot convert argument to rgb sequence

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "[...]/matplotlib/lib/matplotlib/colors.py", line 370, in to_rgba
    r, g, b = self.to_rgb(arg)
  File "[...]/matplotlib/lib/matplotlib/colors.py", line 328, in to_rgb
    'to_rgb: Invalid rgb arg "%s"\n%s' % (str(arg), exc))
ValueError: to_rgb: Invalid rgb arg "None"
cannot convert argument to rgb sequence

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./scratch.py", line 9, in <module>
    plt.plot(list(range(5)))
  File "[...]/matplotlib/lib/matplotlib/pyplot.py", line 3092, in plot
    ax = gca()
  File "[...]/matplotlib/lib/matplotlib/pyplot.py", line 827, in gca
    ax =  gcf().gca(**kwargs)
  File "[...]/matplotlib/lib/matplotlib/figure.py", line 1288, in gca
    return self.add_subplot(1, 1, 1, **kwargs)
  File "[...]/matplotlib/lib/matplotlib/figure.py", line 973, in add_subplot
    a = subplot_class_factory(projection_class)(self, *args, **kwargs)
  File "[...]/matplotlib/lib/matplotlib/axes/_subplots.py", line 73, in __init__
    self._axes_class.__init__(self, fig, self.figbox, **kwargs)
  File "[...]/matplotlib/lib/matplotlib/axes/_base.py", line 422, in __init__
    self.spines = self._gen_axes_spines()
  File "[...]/matplotlib/lib/matplotlib/axes/_base.py", line 812, in _gen_axes_spines
    'left': mspines.Spine.linear_spine(self, 'left'),
  File "[...]/matplotlib/lib/matplotlib/spines.py", line 454, in linear_spine
    result = cls(axes, spine_type, path, **kwargs)
  File "[...]/matplotlib/lib/matplotlib/spines.py", line 54, in __init__
    super(Spine, self).__init__(**kwargs)
  File "[...]/matplotlib/lib/matplotlib/patches.py", line 111, in __init__
    self.set_edgecolor(edgecolor)
  File "[...]/matplotlib/lib/matplotlib/patches.py", line 274, in set_edgecolor
    self._edgecolor = colors.colorConverter.to_rgba(color, self._alpha)
  File "[...]/matplotlib/lib/matplotlib/colors.py", line 376, in to_rgba
    'to_rgba: Invalid rgba arg "%s"\n%s' % (str(arg), exc))
ValueError: to_rgba: Invalid rgba arg "None"
to_rgb: Invalid rgb arg "None"
cannot convert argument to rgb sequence

This particular error can be fixed with

diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py
index 772da0f..810a528 100644
--- a/lib/matplotlib/colors.py
+++ b/lib/matplotlib/colors.py
@@ -342,7 +342,7 @@ def to_rgba(self, arg, alpha=None):
         *alpha* will replace the original *A*.
         """
         try:
-            if arg.lower() == 'none':
+            if arg is None or arg.lower() == 'none':
                 return (0.0, 0.0, 0.0, 0.0)
         except AttributeError:
             pass

A few other places also seem to expect a string.

lib/matplotlib/collections.py:572:            if c.lower() == 'none':
lib/matplotlib/collections.py:611:            if c.lower() == 'none':
lib/matplotlib/colors.py:393:            if nc == 0 or c.lower() == 'none':
lib/matplotlib/lines.py:725:            if is_string_like(edgecolor) and edgecolor.lower() == 'none':
lib/matplotlib/lines.py:1155:        if is_string_like(facecolor) and facecolor.lower() == 'none':
lib/matplotlib/lines.py:1163:        if is_string_like(facecolor) and facecolor.lower() == 'none':

Should these cases be updated to support None? I'd be happy to submit a PR, but I'm not clear on what the intended behavior is.

@efiring
Copy link
Member

efiring commented Mar 5, 2015

The intended behavior is that the None object is not supported; it should always be a string.

@kyleam
Copy link
Author

kyleam commented Mar 5, 2015

Then should validate_colors return a string instead of None?

@efiring
Copy link
Member

efiring commented Mar 5, 2015

Yes. The None object can be used as a kwarg in a function call to indicate that the default should be used. In that case, it is the function's responsibility to find the default in rcParams and use it to replace the None object with a valid color specification (string or tuple) before it goes any farther.

@efiring
Copy link
Member

efiring commented Mar 5, 2015

@tacaswell The relevant PR is #3792, which you merged as 92e608d. It looks like this needs to be redesigned. The None object should not be a valid rcParams entry, and this PR relies on it; in the process of doing so, it wrecks the ability to use 'none' as a color spec in rcParams.

@tacaswell
Copy link
Member

tacaswell commented Mar 5, 2015 via email

@efiring
Copy link
Member

efiring commented Mar 5, 2015

Things will be broken no matter what we do; the new validator approach would not allow the 'none' color spec to be used in this location. The basic problem is that this was an attempt to introduce a forwarding functionality without putting in a proper mechanism for it. The good thing is that this is only in master, not in color_overhaul, so I think that we can simply revert most of it, and no one will have a problem. We can leave in the new kwargs, but leave out the forwarding (or alias, or whatever it should be called) until we have a suitable mechanism for it. Perhaps it could be handled with a new keyword and a new validator, as an ad-hoc way of managing a small number of such cases.
Or let the rcParams be optional; if legend doesn't find them, it uses the axes values.

tacaswell added a commit to tacaswell/matplotlib that referenced this issue Mar 5, 2015
Possible fix for matplotlib#4192.

This adds a new validation (validate_color_or_None) method for color
which allows None and restores `validate_color` to fail on None.

This will allow selected color rcparams to be `None` (not `'None'`)
which the library should interpret as "don't use this rcparam".
tacaswell added a commit to tacaswell/matplotlib that referenced this issue Mar 5, 2015
Possible fix for matplotlib#4192.

This adds a new validation (validate_color_or_None) method for color
which allows None and restores `validate_color` to fail on None.

This will allow selected color rcparams to be `None` (not `'None'`)
which the library should interpret as "don't use this rcparam".
tacaswell added a commit to tacaswell/matplotlib that referenced this issue Mar 5, 2015
Possible fix for matplotlib#4192.

This adds a new validation (validate_color_or_None) method for color
which allows None and restores `validate_color` to fail on None.

This will allow selected color rcparams to be `None` (not `'None'`)
which the library should interpret as "don't use this rcparam".
@tacaswell
Copy link
Member

@efiring I reverted in c90469b

tacaswell added a commit to tacaswell/matplotlib that referenced this issue Mar 14, 2015
Possible fix for matplotlib#4192.

This adds a new validation (validate_color_or_None) method for color
which allows None and restores `validate_color` to fail on None.

This will allow selected color rcparams to be `None` (not `'None'`)
which the library should interpret as "don't use this rcparam".
tacaswell added a commit to tacaswell/matplotlib that referenced this issue Mar 14, 2015
Possible fix for matplotlib#4192.

This adds a new validation (validate_color_or_None) method for color
which allows None and restores `validate_color` to fail on None.

This will allow selected color rcparams to be `None` (not `'None'`)
which the library should interpret as "don't use this rcparam".
tacaswell added a commit to tacaswell/matplotlib that referenced this issue Mar 14, 2015
Possible fix for matplotlib#4192.

This adds a new validation (validate_color_or_None) method for color
which allows None and restores `validate_color` to fail on None.

This will allow selected color rcparams to be `None` (not `'None'`)
which the library should interpret as "don't use this rcparam".
@tacaswell
Copy link
Member

Closed by #4193

@QuLogic QuLogic added this to the v1.5.0 milestone Feb 16, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants