Repository: matplotlib/matplotlib
File: lib/matplotlib/contour.py (Python)

Code before:
        uppers = self._levels[1:]
        return (lowers, uppers)

    def changed(self):
        if not hasattr(self, "cvalues"):
            self._process_colors()  # Sets cvalues.
        # Force an autoscale immediately because self.to_rgba() calls
        # autoscale_None() internally with the data passed to it,
        # so if vmin/vmax are not set yet, this would override them with
        # content from *cvalues* rather than levels like we want
        self.norm.autoscale_None(self.levels)
        self.set_array(self.cvalues)
        self.update_scalarmappable()
        alphas = np.broadcast_to(self.get_alpha(), len(self.cvalues))
        for label, cv, alpha in zip(self.labelTexts, self.labelCValues, alphas):
            label.set_alpha(alpha)
            label.set_color(self.labelMappable.to_rgba(cv))
        super().changed()

    def _ensure_locator_exists(self, N):
        """
        Set a locator on this ContourSet if it's not already set.

        If *N* is an int, it is used as the target number of levels.
        Otherwise when *N* is None, a reasonable default is chosen;
        for logscales the LogLocator chooses, N=7 is the default
        otherwise.

        Parameters
        ----------
        N : int or None
        """
        if self.locator is None:
            if self.logscale:
                self.locator = ticker.LogLocator(numticks=N)
            else:
                if N is None:
                    N = 7  # Hard coded default
                self.locator = ticker.MaxNLocator(N + 1, min_n_ticks=1)

    def _autolev(self):
        """
        Select contour levels to span the data.

        We need two more levels for filled contours than for
        line contours, because for the latter we need to specify
        the lower and upper boundary of each range. For example,
        a single contour boundary, say at z = 0, requires only
        one contour line, but two filled regions, and therefore
        three levels to provide boundaries for both regions.
        """

Review comment (suggestion):
This really should go in the description of `N`, no?
```suggestion
        Parameters
        ----------
        N : int or None
            If *N* is an int, it is used as the target number of levels.
            Otherwise when *N* is None, a reasonable default is chosen;
            for log scales the LogLocator chooses, N=7 is the default
            otherwise.
```

Code after:
        uppers = self._levels[1:]
        return (lowers, uppers)

    def changed(self):
        if not hasattr(self, "cvalues"):
            self._process_colors()  # Sets cvalues.
        # Force an autoscale immediately because self.to_rgba() calls
        # autoscale_None() internally with the data passed to it,
        # so if vmin/vmax are not set yet, this would override them with
        # content from *cvalues* rather than levels like we want
        self.norm.autoscale_None(self.levels)
        self.set_array(self.cvalues)
        self.update_scalarmappable()
        alphas = np.broadcast_to(self.get_alpha(), len(self.cvalues))
        for label, cv, alpha in zip(self.labelTexts, self.labelCValues, alphas):
            label.set_alpha(alpha)
            label.set_color(self.labelMappable.to_rgba(cv))
        super().changed()

    def _ensure_locator_exists(self, N):
        """
        Set a locator on this ContourSet if it's not already set.

        Parameters
        ----------
        N : int or None
            If *N* is an int, it is used as the target number of levels.
            Otherwise when *N* is None, a reasonable default is chosen;
            for logscales the LogLocator chooses, N=7 is the default
            otherwise.
        """
        if self.locator is None:
            if self.logscale:
                self.locator = ticker.LogLocator(numticks=N)
            else:
                if N is None:
                    N = 7  # Hard coded default
                self.locator = ticker.MaxNLocator(N + 1, min_n_ticks=1)

    def _autolev(self):
        """
        Select contour levels to span the data.

        We need two more levels for filled contours than for
        line contours, because for the latter we need to specify
        the lower and upper boundary of each range. For example,
        a single contour boundary, say at z = 0, requires only
        one contour line, but two filled regions, and therefore
        three levels to provide boundaries for both regions.
        """
        lev = self.locator.tick_values(self.zmin, self.zmax)