Skip to content

Commit 765d452

Browse files
authored
Merge pull request #14040 from ianthomas23/10167_tricontour_non_finite_z
Gracefully handle non-finite z in tricontour (issue #10167)
2 parents f1975a7 + c2d6399 commit 765d452

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

lib/matplotlib/tests/test_triangulation.py

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

lib/matplotlib/tri/tricontour.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,24 @@ 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 must not contain masked points within the '
92+
'triangulation')
93+
if not np.isfinite(z_check).all():
94+
raise ValueError('z array must not contain non-finite values '
95+
'within the triangulation')
96+
97+
z = np.ma.masked_invalid(z, copy=False)
98+
self.zmax = float(z_check.max())
99+
self.zmin = float(z_check.min())
88100
if self.logscale and self.zmin <= 0:
89101
raise ValueError('Cannot %s log of negative values.' % fn)
90102
self._contour_level_args(z, args[1:])

0 commit comments

Comments
 (0)