Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

BUG: Fix fill_between when NaN values are present #1140

Merged
merged 3 commits into from

3 participants

@tonysyu

When NaN values are passed to fill_between, the nan value gets replaced by a value at the origin. This PR reuses the function's mask handling to produce a more user-friendly result.

Here's an example demonstrating the issue.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi, 50)
y = np.sin(x)
y[10] = np.nan
y[30] = np.nan
plt.fill_between(x, y)
plt.show()
@efiring
Owner

I think a simpler and more obvious way to accomplish this is change np.asanyarray to np.ma.masked_invalid in the three lines near the top of the function. There is also a cbook.safe_masked_invalid, but it has no docstring, and I don't know what danger it is protecting against--even though I see that I was the one who added it, back in 2009. I suspect it might have been a problem with earlier numpy versions, because a little quick checking does not turn up anything that ma.masked_invalid can't handle.

@tonysyu

@efiring Indeed, np.ma.masked_invalid is much cleaner. Updated PR.

@efiring efiring merged commit 4832bac into from
@pelson

Turns out this registered a unit converter. See #1263.

My bad. Good catch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 23, 2012
  1. @tonysyu
  2. @tonysyu
Commits on Aug 25, 2012
  1. @tonysyu
This page is out of date. Refresh to see the latest.
Showing with 8 additions and 13 deletions.
  1. +8 −13 lib/matplotlib/axes.py
View
21 lib/matplotlib/axes.py
@@ -16,7 +16,6 @@
import matplotlib.collections as mcoll
import matplotlib.colors as mcolors
import matplotlib.contour as mcontour
-import matplotlib.dates as mdates
from matplotlib import docstring
import matplotlib.font_manager as font_manager
import matplotlib.image as mimage
@@ -6719,9 +6718,9 @@ def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
self._process_unit_info(ydata=y2)
# Convert the arrays so we can work with them
- x = np.asanyarray(self.convert_xunits(x))
- y1 = np.asanyarray(self.convert_yunits(y1))
- y2 = np.asanyarray(self.convert_yunits(y2))
+ x = ma.masked_invalid(self.convert_xunits(x))
+ y1 = ma.masked_invalid(self.convert_yunits(y1))
+ y2 = ma.masked_invalid(self.convert_yunits(y2))
if y1.ndim == 0:
y1 = np.ones_like(x)*y1
@@ -6736,14 +6735,12 @@ def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
if not (x.shape == y1.shape == y2.shape == where.shape):
raise ValueError("Argument dimensions are incompatible")
- mask = reduce(ma.mask_or,
- [ma.getmask(x), ma.getmask(y1), ma.getmask(y2)])
+ mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)])
if mask is not ma.nomask:
where &= ~mask
polys = []
for ind0, ind1 in mlab.contiguous_regions(where):
- theseverts = []
xslice = x[ind0:ind1]
y1slice = y1[ind0:ind1]
y2slice = y2[ind0:ind1]
@@ -6853,9 +6850,9 @@ def fill_betweenx(self, y, x1, x2=0, where=None, **kwargs):
self._process_unit_info(xdata=x2)
# Convert the arrays so we can work with them
- y = np.asanyarray(self.convert_yunits(y))
- x1 = np.asanyarray(self.convert_xunits(x1))
- x2 = np.asanyarray(self.convert_xunits(x2))
+ y = ma.masked_invalid(self.convert_yunits(y))
+ x1 = ma.masked_invalid(self.convert_xunits(x1))
+ x2 = ma.masked_invalid(self.convert_xunits(x2))
if x1.ndim == 0:
x1 = np.ones_like(y)*x1
@@ -6870,14 +6867,12 @@ def fill_betweenx(self, y, x1, x2=0, where=None, **kwargs):
if not (y.shape == x1.shape == x2.shape == where.shape):
raise ValueError("Argument dimensions are incompatible")
- mask = reduce(ma.mask_or,
- [ma.getmask(y), ma.getmask(x1), ma.getmask(x2)])
+ mask = reduce(ma.mask_or, [ma.getmask(a) for a in (y, x1, x2)])
if mask is not ma.nomask:
where &= ~mask
polys = []
for ind0, ind1 in mlab.contiguous_regions(where):
- theseverts = []
yslice = y[ind0:ind1]
x1slice = x1[ind0:ind1]
x2slice = x2[ind0:ind1]
Something went wrong with that request. Please try again.