matplotlib/matplotlib · error · AttributeError
'Spines' object does not contain a '{name}' spine
Error message
'Spines' object does not contain a '{name}' spine What it means
Spines maps attribute access onto its internal dict: ax.spines.left returns the 'left' Spine. When the name is neither a real Spines attribute nor a key in the dict, __getattr__ raises this AttributeError. Typical causes: a typo ('leftt'), a name that does not exist on that Axes class ('polar' on a Cartesian Axes), or access after the spine was removed with del ax.spines['top'].
Source
Thrown at lib/matplotlib/spines.py:590
"""
def __init__(self, **kwargs):
self._dict = kwargs
@classmethod
def from_dict(cls, d):
return cls(**d)
def __getstate__(self):
return self._dict
def __setstate__(self, state):
self.__init__(**state)
def __getattr__(self, name):
try:
return self._dict[name]
except KeyError:
raise AttributeError(
f"'Spines' object does not contain a '{name}' spine")
def __getitem__(self, key):
if isinstance(key, list):
unknown_keys = [k for k in key if k not in self._dict]
if unknown_keys:
raise KeyError(', '.join(unknown_keys))
return SpinesProxy({k: v for k, v in self._dict.items()
if k in key})
if isinstance(key, tuple):
raise ValueError('Multiple spines must be passed as a single list')
if isinstance(key, slice):
if key.start is None and key.stop is None and key.step is None:
return SpinesProxy(self._dict)
else:
raise ValueError(
'Spines does not support slicing except for the fully '
'open slice [:] to access all spines.')View on GitHub (pinned to b379c1b69e)
Solutions
- Check membership first: if 'top' in ax.spines: ax.spines['top'].set_visible(False)
- Use the documented names: 'left', 'right', 'top', 'bottom' plus projection-specific ones ('polar', 'inner', 'geo')
- Re-add a deleted spine with ax.spines['top'] = Spine.linear_spine(ax, 'top')
Example fix
# before
ax.spines.toop.set_visible(False) # AttributeError: no 'toop' spine
# after
if 'top' in ax.spines:
ax.spines['top'].set_visible(False) Defensive patterns
Strategy: type-guard
Validate before calling
if 'top' in ax.spines: # membership check before access
ax.spines['top'].set_visible(False) Type guard
def has_spine(ax, name: str) -> bool:
return name in ax.spines # hasattr(ax.spines, name) also works Try / catch
try:
spine = ax.spines[name]
except (AttributeError, KeyError):
spine = None # spine absent on this Axes type; skip styling Prevention
- Check 'name' in ax.spines or hasattr(ax.spines, name) before attribute access
- Remember projection Axes carry different spine names ('polar', 'inner', 'geo')
- Style code reused across Axes types should iterate ax.spines.keys(), not hardcode names
When it happens
Trigger: ax.spines.leftt; getattr(ax.spines, name) for configured names that are absent on this Axes; ax.spines.top after `del ax.spines['top']`.
Common situations: Style code written for one Axes type reused on another (polar, 3D, geo); config-driven spine styling where names come from a file and are never checked.
Related errors
- 'SpinesProxy' object has no attribute '{name}'
- {cls.__name__}.set() got an unexpected keyword argument {pro
- {self.o} has no function {name}
- Unknown property {k}
- spine_type: {self.spine_type} not supported
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/15d670dee5a99c7c.
Report an issue: GitHub.