Closed
Description
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: