Thanks to visit codestin.com
Credit goes to github.com

Skip to content

plt.scatter crashes because overwrites the colors to an empty list #12664

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

Closed
massich opened this issue Oct 29, 2018 · 7 comments
Closed

plt.scatter crashes because overwrites the colors to an empty list #12664

massich opened this issue Oct 29, 2018 · 7 comments

Comments

@massich
Copy link

massich commented Oct 29, 2018

Bug report

Bug summary
When doing scatter plot of nan values it crashes because the list of colors gets overwriten to an empty list by this line:

xs, ys, zs, s, c = cbook.delete_masked_points(xs, ys, zs, s, c)

Code for reproduction
We hit this bug in mne-tools/mne-python#5676, but here is a MWE. Most probably this is a duplicated of #12641. In which case, this can be used as a test.

import matplotlib.pyplot as plt
import numpy as np

n_points = 4
xs = ys = zs = np.full(n_points, np.nan)
colors = list(np.full(2, 'k'))
plt.scatter(xs, ys, zs, c=colors)
plt.show()

Expected outcome

(As in matplotlib 2.2.2) we would expect an empty plot with no error

In [25]: matplotlib.__version__
Out[25]: '2.2.2'

In [26]: %paste
import matplotlib.pyplot as plt
import numpy as np

n_points = 4
xs = ys = zs = np.full(n_points, np.nan)
colors = list(np.full(2, 'k'))
plt.scatter(xs, ys, zs, c=colors)
plt.show()
## -- End pasted text --

In [27]: 

Actual outcome
It breaks because cannot iterate over c

In [9]: matplotlib.__version__
Out[9]: '3.0.1'

In [10]: %paste
import matplotlib.pyplot as plt
import numpy as np

n_points = 4
xs = ys = zs = np.full(n_points, np.nan)
colors = list(np.full(2, 'k'))
plt.scatter(xs, ys, zs, c=colors)
plt.show()
## -- End pasted text --
Traceback (most recent call last):
  File "<ipython-input-10-f59e87d45c38>", line 7, in <module>
    plt.scatter(xs, ys, zs, c=colors)
  File "/home/sik/miniconda3/envs/mne/lib/python3.6/site-packages/matplotlib/pyplot.py", line 2864, in scatter
    is not None else {}), **kwargs)
  File "/home/sik/miniconda3/envs/mne/lib/python3.6/site-packages/matplotlib/__init__.py", line 1805, in inner
    return func(ax, *args, **kwargs)
  File "/home/sik/miniconda3/envs/mne/lib/python3.6/site-packages/matplotlib/axes/_axes.py", line 4234, in scatter
    .format(nc=n_elem, xs=x.size, ys=y.size)
ValueError: 'c' argument has 2 elements, which is not acceptable for use with 'x' with size 4, 'y' with size 4.
@ImportanceOfBeingErnest
Copy link
Member

Bisects to #11383; also relevant #11373.

The scatter documentation is rather clear

x, y : array_like, shape (n, )
c : color, sequence, or sequence of color, optional, default: 'b'
The marker color. Possible values:
[...]
A sequence of color specifications of length n.

So I think it was never intended that x and c are of different length. (And that is independent if them containing nans, or not.) I think the fact that it worked in some previous version was just an implementation detail. Or is there an argument that the colors should be cycled through?

@massich massich closed this as completed Oct 29, 2018
@anntzer
Copy link
Contributor

anntzer commented Oct 29, 2018

See also #12021, I guess...

@massich
Copy link
Author

massich commented Oct 29, 2018

I mess up the MWE. It was supposed to be this one:

In [2]: import matplotlib.pyplot as plt
   ...: import numpy as np
   ...: 
   ...: n_points = 4
   ...: xs = ys = zs = np.full(n_points, np.nan)
   ...: colors = list(np.full(n_points, 'k'))
   ...: plt.scatter(xs, ys, zs, c=colors)
   ...: plt.show()

In that case, they are all the same and the tests passh. Which means that my MWE was wrong. I'll repoen if needed.

@massich massich reopened this Oct 29, 2018
@massich
Copy link
Author

massich commented Oct 29, 2018

Sorry it was needing to be 3D.

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D  # noqa: F401 unused import

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

n_points = 4
xs = ys = zs = np.full(n_points, np.nan)
colors = list(np.full(n_points, 'k'))
ax.scatter(xs, ys, zs, c=colors)
plt.show()

And this is the error:

IndexError: index 0 is out of bounds for axis 0 with size 0

@massich
Copy link
Author

massich commented Oct 29, 2018

@ImportanceOfBeingErnest Sorry I mess up the snipped, I think that the error is related to #11373. Feel free to close if the issue is irrelevant. Sorry for the noise.

@ImportanceOfBeingErnest
Copy link
Member

The new 3D code with equal length lists bisects to #12431, which is the same PR that introduced the problem in #12641. So I guess we can close this.

@massich
Copy link
Author

massich commented Oct 29, 2018

Thx.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants