matplotlib/matplotlib · error · ValueError
total and sep cannot both be None when using layout mode 'eq
Error message
total and sep cannot both be None when using layout mode 'equal'
What it means
offsetbox._get_packed_offsets, the layout engine used by HPacker/VPacker (and everything built on them, like AnnotationBbox legends), distributes children according to mode. In mode='equal' every child gets an equal slice of the available space; the total slice size is derived either from the packer's fixed width/height ('total') or from the per-item gap 'sep'. When both total and sep are None the spacing is underdetermined, so it raises ValueError("total and sep cannot both be None when using layout mode 'equal'").
Source
Thrown at lib/matplotlib/offsetbox.py:142
elif mode == "expand":
# This is a bit of a hack to avoid a TypeError when *total*
# is None and used in conjugation with tight layout.
if total is None:
total = 1
if len(widths) > 1:
sep = (total - sum(widths)) / (len(widths) - 1)
else:
sep = 0
offsets_ = np.cumsum([0] + [w + sep for w in widths])
offsets = offsets_[:-1]
return total, offsets
elif mode == "equal":
maxh = max(widths)
if total is None:
if sep is None:
raise ValueError("total and sep cannot both be None when "
"using layout mode 'equal'")
total = (maxh + sep) * len(widths)
else:
sep = total / len(widths) - maxh
offsets = (maxh + sep) * np.arange(len(widths))
return total, offsets
def _get_aligned_offsets(yspans, height, align="baseline"):
"""
Align boxes each specified by their ``(y0, y1)`` spans.
For simplicity of the description, the terminology used here assumes a
horizontal layout (i.e., vertical alignment), but the function works
equally for a vertical layout.
Parameters
----------View on GitHub (pinned to b379c1b69e)
Solutions
- Give the packer an explicit size: HPacker(..., width=300, mode='equal') (width/height are in pixels).
- Or give an explicit separator: HPacker(..., sep=5, mode='equal') (sep in points).
- If you want auto-sized tight packing, use the default mode='fixed' instead of 'equal'.
- Note the error fires at draw time — fix the constructor arguments in the traceback's packer creation frame, not where savefig appears.
Example fix
# before box = offsetbox.HPacker(children=[a, b], mode='equal', sep=None, width=None) # after box = offsetbox.HPacker(children=[a, b], mode='equal', width=200)
Defensive patterns
Strategy: validation
Validate before calling
def make_hpacker(children, mode='equal', width=None, sep=None):
if mode == 'equal' and width is None and sep is None:
sep = 5 # or raise with a clear message naming the packer
return offsetbox.HPacker(children=children, mode=mode, width=width, sep=sep) Prevention
- With mode='equal', always pass an explicit width (HPacker) / height (VPacker) or sep.
- Remember the error surfaces at draw time; set a breakpoint on the packer constructor, not on savefig.
- Use mode='fixed' for auto-sized tight packing.
When it happens
Trigger: HPacker(children=[...], mode='equal', width=None, sep=None) or VPacker(mode='equal', height=None, sep=None); subclasses of PackerBase that forward None width/sep with mode='equal'; drawing (savefig/show) triggers _get_bbox_and_child_offsets, where the error surfaces at draw time.
Common situations: Migrating layouts that used mode='fixed' to 'equal' and passing sep=None to 'let it auto-size'; constructing custom OffsetBox toolbars/legends where the container size is only known later; the error appearing only at render time, confusing the stack trace.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Width and height specified must be non-negative
- argument must be among %s
- Specifying 'loc' is disallowed when any of its corresponding
- Invalid value for 'layout': {layout!r}
- Number of rows must be a positive integer, not {nrows!r}
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/a0c4630116f5af7a.
Report an issue: GitHub.