Skip to content

Issue when setting scatter color in separate method call #10381

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
astrofrog opened this issue Feb 5, 2018 · 5 comments
Closed

Issue when setting scatter color in separate method call #10381

astrofrog opened this issue Feb 5, 2018 · 5 comments
Milestone

Comments

@astrofrog
Copy link
Contributor

For an application I am developing, I need to call ax.scatter then change the colors of the points after the fact. However, if the input x/y values contain NaN values, then setting the colors after the fact doesn't work properly. The following example:

import matplotlib
matplotlib.use('Agg')

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, aspect='auto')

x = np.array([1, 2, 3])
y = np.array([2, np.nan, 4])
c = np.array([3, 4, 5])

s = ax.scatter(x, y, c=c, vmin=3, vmax=5, s=320, zorder=1, edgecolor='none')

s = ax.scatter(x, y, s=160, zorder=2, edgecolor='none')
s.set_array(c)
s.set_clim(3, 5)

s = ax.scatter([], [], s=40, zorder=3, edgecolor='none')
s.set_offsets(np.vstack([x, y]).transpose())
s.set_array(c)
s.set_clim(3, 5)

fig.savefig('test.png')

produces the following output:

test

The top right point should be all yellow. However it isn't, because in the scatter call, invalid values are removed, so when I try and set the colors with set_array, the color values are offset from the x/y values. In the final case, things work since the 'bad' values are masked from neither the offsets nor the colors.

Is there a way to achieve something along the lines of the middle example (setting the colors after the fact)

@tacaswell
Copy link
Member

This is because we create the initial artist and strip out any points that have nan in them. The new colors will then be offset from where you think they should be.

attn @efiring as you have been working around this code recently.

@tacaswell tacaswell added this to the v3.0 milestone Feb 5, 2018
@efiring
Copy link
Member

efiring commented Feb 5, 2018

I think that adding the requested functionality will require writing a subclass of PathCollection that can keep track of the original inputs, and can repeat the mask- and nan-filtering operation every time a relevant property is updated.

@anntzer
Copy link
Contributor

anntzer commented Feb 6, 2018

Do we actually need to filter out the nans (except for backcompatibility considerations)? Aren't the renderers supposed to be able to handle nan data to start with anyways?

@efiring
Copy link
Member

efiring commented Feb 7, 2018

Good question; maybe they all can. If so, taking advantage of that would require some substantial changes, I think, because we support masked arrays, and use them internally. Going 100% with nans for missing values implies always using floating point, and switching from .max to .nanmax etc.

@tacaswell tacaswell modified the milestones: v3.0, v3.1 Aug 11, 2018
efiring added a commit to efiring/matplotlib that referenced this issue Oct 6, 2018
anntzer pushed a commit to efiring/matplotlib that referenced this issue Nov 13, 2018
anntzer pushed a commit to efiring/matplotlib that referenced this issue Nov 14, 2018
anntzer pushed a commit to efiring/matplotlib that referenced this issue Dec 12, 2018
@tacaswell tacaswell modified the milestones: v3.1.0, v3.2.0 Mar 18, 2019
@efiring
Copy link
Member

efiring commented Apr 15, 2019

I think this is closed by #12422. If not, please reopen.

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

5 participants