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
- Use one of the four accepted forms: None, 'scott', 'silverman', a plain float/int, or a callable like lambda kde: kde.n ** -0.2.
- If the value arrives as a 1-element sequence, unwrap it: bw = float(bw[0]).
- Validate at the config boundary: reject unknown strings early with your own error message.
- 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
- Whitelist bw_method at the config boundary: None | 'scott' | 'silverman' | float | callable.
- Unwrap single-element sequences from configs before passing.
- Never forward raw user strings — map them to allowed values first.
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
- noverlap must be less than NFFT
- x and y must be equal if mode is not 'psd'
- `dataset` input should have multiple elements.
- points have dimension {dim}, dataset has dimension {self.dim
- markevery={markevery!r} is not a recognized value
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/f0e52bd1d3f48d37.
Report an issue: GitHub.