From 6ac197fd58404633499c3fb7bacc461c3c1666f9 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Sun, 4 Jun 2017 11:09:24 -1000 Subject: [PATCH] BUG: handle empty levels array in contour, closes #7486 This relates to line contours only, not to filled contours. This handles the case where an empty array is provided as the "levels" kwarg, or where for any reason there are no levels within the data range. An example is the case of uniform z. The levels array is then set to the minimum value of z so that the plotting can proceed, and a warning is generated. --- lib/matplotlib/contour.py | 21 ++++++++++++++------- lib/matplotlib/tests/test_contour.py | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py index 82d9fb023312..d4692e1610a5 100644 --- a/lib/matplotlib/contour.py +++ b/lib/matplotlib/contour.py @@ -1132,14 +1132,10 @@ def _autolev(self, N): self.locator = ticker.LogLocator() else: self.locator = ticker.MaxNLocator(N + 1, min_n_ticks=1) - zmax = self.zmax - zmin = self.zmin - lev = self.locator.tick_values(zmin, zmax) + + lev = self.locator.tick_values(self.zmin, self.zmax) self._auto = True - if self.filled: - return lev - # For line contours, drop levels outside the data range. - return lev[(lev > zmin) & (lev < zmax)] + return lev def _contour_level_args(self, z, args): """ @@ -1165,6 +1161,17 @@ def _contour_level_args(self, z, args): "Last {0} arg must give levels; see help({0})" .format(fn)) self.levels = lev + else: + self.levels = np.asarray(self.levels).astype(np.float64) + + if not self.filled: + inside = (self.levels > self.zmin) & (self.levels < self.zmax) + self.levels = self.levels[inside] + if len(self.levels) == 0: + self.levels = [self.zmin] + warnings.warn("No contour levels were found" + " within the data range.") + if self.filled and len(self.levels) < 2: raise ValueError("Filled contours require at least 2 levels.") diff --git a/lib/matplotlib/tests/test_contour.py b/lib/matplotlib/tests/test_contour.py index 5e2211066f3c..d45540325c15 100644 --- a/lib/matplotlib/tests/test_contour.py +++ b/lib/matplotlib/tests/test_contour.py @@ -132,6 +132,28 @@ def test_contour_shape_invalid_2(): excinfo.match(r'Input z must be a 2D array.') +def test_contour_empty_levels(): + + x = np.arange(9) + z = np.random.random((9, 9)) + + fig, ax = plt.subplots() + with pytest.warns(UserWarning) as record: + ax.contour(x, x, z, levels=[]) + assert len(record) == 1 + + +def test_contour_uniform_z(): + + x = np.arange(9) + z = np.ones((9, 9)) + + fig, ax = plt.subplots() + with pytest.warns(UserWarning) as record: + ax.contour(x, x, z) + assert len(record) == 1 + + @image_comparison(baseline_images=['contour_manual_labels']) def test_contour_manual_labels():