Skip to content
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

fill_between interpolation & nan issue #11781

Closed
Phlya opened this issue Jul 27, 2018 · 16 comments
Closed

fill_between interpolation & nan issue #11781

Phlya opened this issue Jul 27, 2018 · 16 comments

Comments

@Phlya
Copy link
Contributor

Phlya commented Jul 27, 2018

The issue was discovered here
deeptools/pyGenomeTracks#37

Basically, when fill_between encounters a NaN in the y values, when interpolate=True it produces a strange output.

This is without interpolation:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(107).astype(float)
y = np.append(np.zeros((100))+0.01, [0.5, 0.75, 1, np.nan, 1, 0.75, 0.5])

plt.figure(figsize=(20, 5))
plt.fill_between(x, y, interpolate=False)

image

If I turn interpolation on (which I wouldn't expect to do anything in this case, since there are not zero crossings), this is what I get:

plt.figure(figsize=(20, 5))
plt.fill_between(x, y, interpolate=True)

image

Even if I am misunderstanding something about how interpolation is supposed to work, clearly this is not what it should do...

mpl 2.1.2, python 3.5.2

@Phlya
Copy link
Contributor Author

Phlya commented Jul 27, 2018

Another example to clarify what's going on

x = np.arange(107).astype(float)
y = np.append(np.zeros((100))+0.01, [2, 0.75, 1, np.nan, 1, 0.75, 0.5])

plt.figure(figsize=(20, 5))
plt.fill_between(x, y, interpolate=True)

image

@Phlya Phlya changed the title fill_between interpolation issue fill_between interpolation & nan issue Jul 27, 2018
@Phlya
Copy link
Contributor Author

Phlya commented Jul 27, 2018

Also possible to make an example where this fails when there actually are negative values and a where=y>0 condition:

x = np.arange(101).astype(float)
y = np.append(np.zeros((100))+np.random.random(100)-0.05, [np.nan])

plt.figure(figsize=(20, 5))
plt.fill_between(x, y, interpolate=True, where=y>0)

image

@jklymak
Copy link
Member

jklymak commented Jul 27, 2018

While you are testing, have you tried masking instead of passing NaN?

@Phlya
Copy link
Contributor Author

Phlya commented Jul 27, 2018

No, sorry - but can try tomorrow.

@timhoffm
Copy link
Member

Part of the problem is that

_axes.py l.5039:

x, y1, y2 = np.broadcast_arrays(np.atleast_1d(x), y1, y2)

casts the masked arrays back to regular arrays.

_axes.py l.5063ff:

                    if len(diff_values) == 2:
                        if np.ma.is_masked(diff_values[1]):
                            return x[im1], y1[im1]
                        elif np.ma.is_masked(diff_values[0]):
                            return x[ind], y1[ind]

does not have an effect anymore (the invalid values are not masked anymore). It works if you replace np.ma.is_masked()by ~np.isfinite(). No sure if this is the right way to go, though.

@jklymak
Copy link
Member

jklymak commented Jul 27, 2018

Good find; seems like thats definitely the issue.

Marking as "units", because how we normalize arrays after they come to us is tied up in the units discussion. It'd be nice if every x/y data array input to axes methods got the same consistent conversion, and that would certainly include how to handle NaN versus masked....

@Phlya
Copy link
Contributor Author

Phlya commented Jul 28, 2018

Just in case, masking the NaN value doesn't help.

@jklymak
Copy link
Member

jklymak commented Mar 3, 2019

This looks to have been introduced in #7562... ping @anntzer.

@anntzer
Copy link
Contributor

anntzer commented Mar 3, 2019

I can't repro the issue, neither with mpl2.1.2 (original report) or master...

@jklymak
Copy link
Member

jklymak commented Mar 4, 2019

You can't reproduce with interpolate=True?

@anntzer
Copy link
Contributor

anntzer commented Mar 4, 2019

This is what I get when running the example copy-pasted from #11781 (comment) with master:
test

@jklymak
Copy link
Member

jklymak commented Mar 4, 2019

#11781 (comment) ?

@anntzer
Copy link
Contributor

anntzer commented Mar 4, 2019

test

@jklymak
Copy link
Member

jklymak commented Mar 4, 2019

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(107).astype(float)
y = np.append(np.zeros((100))+0.01, [0.5, 0.75, 1, np.nan, 1, 0.75, 0.5])

plt.figure()
plt.fill_between(x, y, interpolate=True)
plt.show()

figure_1

@anntzer
Copy link
Contributor

anntzer commented Mar 4, 2019

What version of numpy? I'm on 1.16.2.
I can't think of anything else...

@jklymak
Copy link
Member

jklymak commented Mar 4, 2019

1.14.6... Upgrading to 1.16 fixes. So, I guess we can close this....

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

4 participants