Skip to content

Commit fdbde0c

Browse files
committed
BUG: Gracefully handle non-finite z in tricontour (matplotlib#10167)
1 parent 769dddd commit fdbde0c

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

lib/matplotlib/tests/test_triangulation.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,3 +1115,27 @@ def test_qhull_large_offset():
11151115
triang = mtri.Triangulation(x, y)
11161116
triang_offset = mtri.Triangulation(x + offset, y + offset)
11171117
assert len(triang.triangles) == len(triang_offset.triangles)
1118+
1119+
1120+
def test_tricontour_non_finite_z():
1121+
# github issue 10167.
1122+
x = [0, 1, 0, 1]
1123+
y = [0, 0, 1, 1]
1124+
triang = mtri.Triangulation(x, y)
1125+
plt.figure()
1126+
1127+
with pytest.raises(ValueError) as excinfo:
1128+
plt.tricontourf(triang, [0, 1, 2, np.inf])
1129+
excinfo.match(r'z array cannot contain non-finite values')
1130+
1131+
with pytest.raises(ValueError) as excinfo:
1132+
plt.tricontourf(triang, [0, 1, 2, -np.inf])
1133+
excinfo.match(r'z array cannot contain non-finite values')
1134+
1135+
with pytest.raises(ValueError) as excinfo:
1136+
plt.tricontourf(triang, [0, 1, 2, np.nan])
1137+
excinfo.match(r'z array cannot contain non-finite values')
1138+
1139+
with pytest.raises(ValueError) as excinfo:
1140+
plt.tricontourf(triang, np.ma.array([0, 1, 2, 3], mask=[1, 0, 0, 0]))
1141+
excinfo.match(r'z cannot be a masked array')

lib/matplotlib/tri/tricontour.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,22 @@ def _contour_args(self, args, kwargs):
7979
fn = 'contour'
8080
tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args,
8181
**kwargs)
82-
z = np.asarray(args[0])
82+
z = np.ma.asarray(args[0])
8383
if z.shape != tri.x.shape:
8484
raise ValueError('z array must have same length as triangulation x'
8585
' and y arrays')
86-
self.zmax = z.max()
87-
self.zmin = z.min()
86+
87+
# z values must be finite, only need to check points that are included
88+
# in the triangulation.
89+
z_check = z[np.unique(tri.get_masked_triangles())]
90+
if np.ma.is_masked(z_check):
91+
raise ValueError('z cannot be a masked array')
92+
if not np.isfinite(z_check).all():
93+
raise ValueError('z array cannot contain non-finite values')
94+
95+
z = np.ma.masked_invalid(z, copy=False)
96+
self.zmax = float(z.max())
97+
self.zmin = float(z.min())
8898
if self.logscale and self.zmin <= 0:
8999
raise ValueError('Cannot %s log of negative values.' % fn)
90100
self._contour_level_args(z, args[1:])

0 commit comments

Comments
 (0)