Skip to content

Correctly skip colors for nan points given to scatter - #7570

Merged
tacaswell merged 6 commits into
matplotlib:masterfrom
dstansby:scatter-nan-colors
Dec 11, 2016
Merged

tacaswell merged 6 commits into
matplotlib:masterfrom
dstansby:scatter-nan-colors

Conversation

@dstansby

@dstansby dstansby commented Dec 5, 2016

Copy link
Copy Markdown
Member

Fixes #3489. As far as I can tell the only problem was that colors was never being masked.

@dstansby dstansby changed the title Correct skip colors for nan points given to scatter Correctly skip colors for nan points given to scatter Dec 5, 2016
@tacaswell tacaswell added this to the 2.0.1 (next bug fix release) milestone Dec 5, 2016
@tacaswell

Copy link
Copy Markdown
Member

attn @efiring as you have been working in this code a lot recently.

Comment thread lib/matplotlib/axes/_axes.py Outdated
@@ -3996,7 +3996,7 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
colors = None # use cmap, norm after collection is created

# c will be unchanged unless it is the same length as x:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c and colors will be unchanged (why are c and colors different args?)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a question you don't want to ask 😈 .

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More seriously, there it pre-dates me and is almost certainly to support back compatibility. c can be a scalar, a color, a sequence of colors or a sequence of scalars. colors can be (iirc) a single color or a list of colors.

c comes from scatter being a scalar mappable under the hood and colors comes from scatter returning a collection under the hood.

colors = np.array(['k', 'w', 'k'])
s = plt.scatter(x, y, color=colors)
facecolors = s.get_facecolors()
assert_array_equal(facecolors[1], np.array([0, 0, 0, 1]))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably unnecessary, but what about a test that verifies it's the right facecolor for the right value? Just to ensure no weird shifting.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to get the scatter points out from s? All I can see that might do it is s.get_paths(), but that seems to give arrays that are definitely not what I'm looking for...

@story645 story645 Dec 5, 2016 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, unfortunately haven't found a direct way though there might be one. :( As much as I'm loath to suggest an image test, that seems to be the trick. Though the way to test the error you're seeing below is to use the s.get_edgecolors(), so maybe that'd be good enough?

@dstansby

dstansby commented Dec 5, 2016 •

Copy link
Copy Markdown
Member Author

Actually plotting the figure in the test with red as the masked color:

import numpy as np
import matplotlib.pyplot as plt

x = np.array([1, 2, 3])
y = np.array([1, np.nan, 3])
colors = np.array(['k', 'r', 'k'])
s = plt.scatter(x, y, color=colors)
plt.show()

gives the output:
figure_2

which is clearly wrong... I'll try and look into this tomorrow.

@tacaswell

Copy link
Copy Markdown
Member

Looks like you missed the edgecolors?

@dstansby

dstansby commented Dec 6, 2016

Copy link
Copy Markdown
Member Author

Okay, I think that's everything masked that needs to be. I couldn't work out whether to mask offsets or not so have left it alone.

linewidths = s.get_linewidths()
assert_array_equal(facecolors[1], np.array([0, 0, 0, 1]))
assert_array_equal(linecolors[1], np.array([0, 0, 0, 1]))
assert linewidths[1] == 3

@story645 story645 Dec 6, 2016 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also maybe assert facecolors[0], name edgecolors = s.get_edgecolors(),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm missing something here - should I just rename facecolors to edgecolors?

@story645

story645 commented Dec 6, 2016 •

Copy link
Copy Markdown
Member

Did you generate a new image to verify that it didn't do anything weird? And test with another marker at least informally?

Also, travis and appveyor are at least somewhat failing on your tests, so please look at that.

@dstansby

dstansby commented Dec 9, 2016

Copy link
Copy Markdown
Member Author

Yep, I have generated a new image locally to check nothing funny is happening any more.

I'm baffled that any of the tests passed to be honest given I was never setting linewidths at all... should be fixed now.

@tacaswell
tacaswell merged commit f787c7a into matplotlib:master Dec 11, 2016
tacaswell added a commit that referenced this pull request Dec 11, 2016
MNT: Correctly skip colors for nan points given to scatter

Conflicts:
    lib/matplotlib/tests/test_axes.py
       Conflicts due to tests added on both branches
@tacaswell

Copy link
Copy Markdown
Member

Thanks! backported as e09a6f7

@dstansby Greatly appreciate all of the work you have been doing recently!

@QuLogic QuLogic modified the milestones: 2.0 (style change major release), 2.0.1 (next bug fix release) Dec 11, 2016
@dstansby
dstansby deleted the scatter-nan-colors branch December 27, 2016 16:42
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

Successfully merging this pull request may close these issues.

4 participants