Skip to content

plt.scatter, error with NaN values and edge color #19066

Closed
@donok1

Description

@donok1

Bug report

Bug summary
When plotting a scatter plot with y containing NaN values, depending on the number of values, an error comes up when setting the color or edgecolor.
This error was introduced with version 3.3.0, might be linked to #17849

Code for reproduction
Here is a basic example

import matplotlib.pyplot as plt
import numpy as np
plt.scatter([1, 2, 3], [ 0, np.nan, 2],color=(1, 0, 0))

Actual outcome

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-77-cf954735eeaf> in <module>
      1 import matplotlib.pyplot as plt
      2 import numpy as np
----> 3 plt.scatter([1, 2, 3], [ 0, np.nan, 2],color=(1, 0, 0))

/usr/local/lib/python3.9/site-packages/matplotlib/pyplot.py in scatter(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, plotnonfinite, data, **kwargs)
   2888         verts=cbook.deprecation._deprecated_parameter,
   2889         edgecolors=None, *, plotnonfinite=False, data=None, **kwargs):
-> 2890     __ret = gca().scatter(
   2891         x, y, s=s, c=c, marker=marker, cmap=cmap, norm=norm,
   2892         vmin=vmin, vmax=vmax, alpha=alpha, linewidths=linewidths,

/usr/local/lib/python3.9/site-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs)
   1445     def inner(ax, *args, data=None, **kwargs):
   1446         if data is None:
-> 1447             return func(ax, *map(sanitize_sequence, args), **kwargs)
   1448 
   1449         bound = new_sig.bind(ax, *args, **kwargs)

/usr/local/lib/python3.9/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs)
    409                          else deprecation_addendum,
    410                 **kwargs)
--> 411         return func(*inner_args, **inner_kwargs)
    412 
    413     return wrapper

/usr/local/lib/python3.9/site-packages/matplotlib/axes/_axes.py in scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, plotnonfinite, **kwargs)
   4486         offsets = np.ma.column_stack([x, y])
   4487 
-> 4488         collection = mcoll.PathCollection(
   4489                 (path,), scales,
   4490                 facecolors=colors,

/usr/local/lib/python3.9/site-packages/matplotlib/collections.py in __init__(self, paths, sizes, **kwargs)
    951         """
    952 
--> 953         super().__init__(**kwargs)
    954         self.set_paths(paths)
    955         self.set_sizes(sizes)

/usr/local/lib/python3.9/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs)
    409                          else deprecation_addendum,
    410                 **kwargs)
--> 411         return func(*inner_args, **inner_kwargs)
    412 
    413     return wrapper

/usr/local/lib/python3.9/site-packages/matplotlib/collections.py in __init__(self, edgecolors, facecolors, linewidths, linestyles, capstyle, joinstyle, antialiaseds, offsets, transOffset, norm, cmap, pickradius, hatch, urls, offset_position, zorder, **kwargs)
    173         self._hatch_color = mcolors.to_rgba(mpl.rcParams['hatch.color'])
    174         self.set_facecolor(facecolors)
--> 175         self.set_edgecolor(edgecolors)
    176         self.set_linewidth(linewidths)
    177         self.set_linestyle(linestyles)

/usr/local/lib/python3.9/site-packages/matplotlib/collections.py in set_edgecolor(self, c)
    828         """
    829         self._original_edgecolor = c
--> 830         self._set_edgecolor(c)
    831 
    832     def set_alpha(self, alpha):

/usr/local/lib/python3.9/site-packages/matplotlib/collections.py in _set_edgecolor(self, c)
    812         except AttributeError:
    813             pass
--> 814         self._edgecolors = mcolors.to_rgba_array(c, self._alpha)
    815         if set_hatch_color and len(self._edgecolors):
    816             self._hatch_color = tuple(self._edgecolors[0])

/usr/local/lib/python3.9/site-packages/matplotlib/colors.py in to_rgba_array(c, alpha)
    339         return np.zeros((0, 4), float)
    340     else:
--> 341         return np.array([to_rgba(cc, alpha) for cc in c])
    342 
    343 

/usr/local/lib/python3.9/site-packages/matplotlib/colors.py in <listcomp>(.0)
    339         return np.zeros((0, 4), float)
    340     else:
--> 341         return np.array([to_rgba(cc, alpha) for cc in c])
    342 
    343 

/usr/local/lib/python3.9/site-packages/matplotlib/colors.py in to_rgba(c, alpha)
    187         rgba = None
    188     if rgba is None:  # Suppress exception chaining of cache lookup failure.
--> 189         rgba = _to_rgba_no_colorcycle(c, alpha)
    190         try:
    191             _colors_full_map.cache[c, alpha] = rgba

/usr/local/lib/python3.9/site-packages/matplotlib/colors.py in _to_rgba_no_colorcycle(c, alpha)
    261     # tuple color.
    262     if not np.iterable(c):
--> 263         raise ValueError(f"Invalid RGBA argument: {orig_c!r}")
    264     if len(c) not in [3, 4]:
    265         raise ValueError("RGBA sequence should have length 3 or 4")

ValueError: Invalid RGBA argument: 1

First analys
It is only affects the edgecolor option, facecolor works fine:

# This work fine
plt.scatter([1, 2, 3], [ 0, np.nan, 2])
plt.scatter([1, 2, 3], [ 0, np.nan, 2], facecolor=(1, 0, 0))

It also seem to be only happening when there are 3 values to plot, 1 or 2 of them being NaNs:

# These all work
plt.scatter([1, 2], [1, np.nan ],color=(1, 0, 0))
plt.scatter([1, 2, 3, 4], [1, 2, np.nan, 4 ],color=(1, 0, 0))
plt.scatter([1, 2, 3, 4, 5], [1, 2, np.nan, 4, 5 ],color=(1, 0, 0))
plt.scatter([1, 2, 3], [np.nan , np.nan , np.nan ],color=(1, 0, 0))
plt.scatter(np.arange(1000), np.append(np.random.rand(999),np.NaN),color=(1, 0, 0))

# But those not
plt.scatter([1, 2, 3], [1, np.nan, np.nan ],color=(1, 0, 0))
plt.scatter([1, 2, 3], [ np.nan, 2, np.nan ],color=(1, 0, 0))

Error was discovered through seaborn, mwaskom/seaborn#2373

Matplotlib version

  • Operating system: Mac OS 10.15 / Windows 10
  • Matplotlib version: >= 3.3.0
  • Matplotlib backend (print(matplotlib.get_backend())): module://ipykernel.pylab.backend_inline
  • Python version: 3.8, 3.9.0
  • Jupyter version (if applicable): 2.2.9
  • Other libraries:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions