matplotlib/matplotlib · error · ValueError

`bw_method` should be 'scott', 'silverman', a scalar or a ca

Error message

`bw_method` should be 'scott', 'silverman', a scalar or a callable

What it means

mlab.GaussianKDE.__init__ accepts bw_method=None (class default), the strings 'scott' or 'silverman' (matched case-insensitively via cbook._str_equal), a numbers.Number used as a constant factor, or a callable receiving the KDE instance. Any other value — a string like 'auto', a list/array, or an object — raises ValueError("`bw_method` should be 'scott', 'silverman', a scalar or a callable").

Source

Thrown at lib/matplotlib/mlab.py:851

        if not np.array(self.dataset).size > 1:
            raise ValueError("`dataset` input should have multiple elements.")

        self.dim, self.num_dp = np.array(self.dataset).shape

        if bw_method is None:
            pass
        elif cbook._str_equal(bw_method, 'scott'):
            self.covariance_factor = self.scotts_factor
        elif cbook._str_equal(bw_method, 'silverman'):
            self.covariance_factor = self.silverman_factor
        elif isinstance(bw_method, Number):
            self._bw_method = 'use constant'
            self.covariance_factor = lambda: bw_method
        elif callable(bw_method):
            self._bw_method = bw_method
            self.covariance_factor = lambda: self._bw_method(self)
        else:
            raise ValueError("`bw_method` should be 'scott', 'silverman', a "
                             "scalar or a callable")

        # Computes the covariance matrix for each Gaussian kernel using
        # covariance_factor().

        self.factor = self.covariance_factor()
        # Cache covariance and inverse covariance of the data
        if not hasattr(self, '_data_inv_cov'):
            self.data_covariance = np.atleast_2d(
                np.cov(
                    self.dataset,
                    rowvar=1,
                    bias=False))
            self.data_inv_cov = np.linalg.inv(self.data_covariance)

        self.covariance = self.data_covariance * self.factor ** 2
        self.inv_cov = self.data_inv_cov / self.factor ** 2
        self.norm_factor = (np.sqrt(np.linalg.det(2 * np.pi * self.covariance))

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Use one of the four accepted forms: None, 'scott', 'silverman', a plain float/int, or a callable like lambda kde: kde.n ** -0.2.
  2. If the value arrives as a 1-element sequence, unwrap it: bw = float(bw[0]).
  3. Validate at the config boundary: reject unknown strings early with your own error message.
  4. For data-driven bandwidths, pass a callable rather than a string identifier.

Example fix

# before
kde = mlab.GaussianKDE(data, bw_method='auto')

# after
bw = {'auto': 'scott', 'default': None}.get(cfg_bw, cfg_bw)
kde = mlab.GaussianKDE(data, bw_method=bw if isinstance(bw, (str, float, int)) or bw is None or callable(bw) else 'scott')
Defensive patterns

Strategy: type-guard

Validate before calling

from numbers import Number

def valid_bw(bw):
    return (bw is None or isinstance(bw, (str, Number)) and not isinstance(bw, bool)
            or callable(bw)) and not isinstance(bw, (list, tuple, np.ndarray))

Type guard

def is_valid_bw_method(bw) -> bool:
    if bw is None or callable(bw):
        return True
    if isinstance(bw, str):
        return bw.lower() in ('scott', 'silverman')
    return isinstance(bw, Number) and not isinstance(bw, bool)

Try / catch

try:
    kde = mlab.GaussianKDE(data, bw_method=bw)
except ValueError:
    kde = mlab.GaussianKDE(data, bw_method='scott')  # explicit fallback default

Prevention

When it happens

Trigger: GaussianKDE(data, bw_method='auto'); bw_method=[0.5] or np.array([0.5]) (arrays are not Number instances); bw_method='Scott' actually passes due to case-insensitive compare, but 'scott factor' or 'cross_validation' fails; passing a method name from another library (e.g. seaborn's bandwidth semantics).

Common situations: Exposing a user-facing bandwidth parameter straight into GaussianKDE without validation; porting scipy examples where bw_method can also be a string scalar like '0.5' (it cannot here); config files storing bw_method as a JSON list.

Related errors


AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21). Data as JSON: /api/errors/f0e52bd1d3f48d37. Report an issue: GitHub.