matplotlib/matplotlib · error · ValueError
Multiple spines must be passed as a single list
Error message
Multiple spines must be passed as a single list
What it means
Spines.__getitem__ accepts a single name (string), a list of names, or the fully open slice [:]. Indexing with a tuple - classically ax.spines[('top', 'right')] written where ax.spines[['top', 'right']] was meant - raises this ValueError; the message states the fix: multiple names must be passed as a single list.
Source
Thrown at lib/matplotlib/spines.py:601
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.')
return self._dict[key]
def __setitem__(self, key, value):
# TODO: Do we want to deprecate adding spines?
self._dict[key] = value
def __delitem__(self, key):
# TODO: Do we want to deprecate deleting spines?
del self._dict[key]
def __iter__(self):View on GitHub (pinned to b379c1b69e)
Solutions
- Use a list: ax.spines[['top', 'right']].set_visible(False)
- Address all spines with ax.spines[:]
- Normalize keys before indexing: names = list(names) if isinstance(names, tuple) else names
Example fix
# before
ax.spines[('top', 'right')].set_visible(False) # ValueError
# after
ax.spines[['top', 'right']].set_visible(False) Defensive patterns
Strategy: validation
Validate before calling
def spine_keys(names):
if isinstance(names, tuple):
names = list(names) # tuple key would raise inside __getitem__
return names
ax.spines[spine_keys(('top', 'right'))].set_visible(False) Prevention
- Always write multiple spine names as a list literal: ax.spines[['top', 'right']]
- Do not carry tuple-indexing habits from pandas .loc into Spines
- Normalize programmatic keys to lists before indexing
When it happens
Trigger: ax.spines[('top', 'right')].set_visible(False) - parentheses around the names instead of a list literal; programmatic key building that produces a tuple.
Common situations: Habits carried over from pandas .loc tuple indexing or numpy multi-axis indexing; list-vs-tuple normalization missing in helper functions.
Related errors
- spine_type: {self.spine_type} not supported
- unable to set bounds for spine "%s"
- position should be 'center' or 2-tuple
- position[0] should be one of 'outward', 'axes', or 'data'
- Spines does not support slicing except for the fully open sl
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/42f6f98cae900a87.
Report an issue: GitHub.