diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py index 77dc58740971..1bb09df44685 100644 --- a/lib/matplotlib/contour.py +++ b/lib/matplotlib/contour.py @@ -1029,8 +1029,12 @@ def _process_contour_level_args(self, args, z_dtype): if self.filled and len(self.levels) < 2: raise ValueError("Filled contours require at least 2 levels.") - if len(self.levels) > 1 and np.min(np.diff(self.levels)) <= 0.0: - raise ValueError("Contour levels must be increasing") + + # check if filled contours are monotonically increasing: + if (self.filled and len(self.levels) > 1 and + np.any(np.diff(self.levels) <= 0)): + raise ValueError( + "Filled contour levels must be monotonically increasing") def _process_levels(self): """ @@ -1496,7 +1500,7 @@ def _initialize_x_y(self, z): *n*=7 is the default. If array-like, draw contour lines at the specified levels. - The values must be in increasing order. + For filled contours, the values must be in increasing order. If not specified, a reasonable default is automatically chosen. For linear scales, this corresponds to *levels=7*. For logarithmic @@ -1519,8 +1523,8 @@ def _initialize_x_y(self, z): The colors of the levels, i.e. the lines for `.contour` and the areas for `.contourf`. - The sequence is cycled for the levels in ascending order. If the - sequence is shorter than the number of levels, it's repeated. + The colors are mapped to the levels in the order specified, repeating as + necessary if there are fewer colors than levels. As a shortcut, a single color may be used in place of one-element lists, i.e. ``'red'`` instead of ``['red']`` to color all levels with the same color. @@ -1641,8 +1645,8 @@ def _initialize_x_y(self, z): If a number, all levels will be plotted with this linewidth. - If a sequence, the levels in ascending order will be plotted with - the linewidths in the order specified. + If a sequence, the linewidths are mapped to the levels in order, + repeating as necessary if there are fewer linewidths than levels. If None, this falls back to :rc:`lines.linewidth`. diff --git a/lib/matplotlib/tests/test_contour.py b/lib/matplotlib/tests/test_contour.py index e242c219df10..54f821e94823 100644 --- a/lib/matplotlib/tests/test_contour.py +++ b/lib/matplotlib/tests/test_contour.py @@ -335,6 +335,22 @@ def test_contourf_decreasing_levels(): plt.contourf(z, [1.0, 0.0]) +@check_figures_equal() +def test_contour_decreasing_levels(fig_ref, fig_test): + # Check that contour works with decreasing levels: + Z = np.arange(100).reshape(10, 10) + ax_ref = fig_ref.subplots() + ax_test = fig_test.subplots() + + levels0 = np.array([6, 10, 20, 30, 33, 53, 80]) + colors0 = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'black'] + + # sorted: + ax_ref.contour(Z, levels=levels0, colors=np.array(colors0)) + # reversed: + ax_test.contour(Z, levels=levels0[::-1], colors=colors0[::-1]) + + def test_contourf_symmetric_locator(): # github issue 7271 z = np.arange(12).reshape((3, 4))