matplotlib/matplotlib · error · ValueError
`rotation_point` must be one of {'xy', 'center', (number, nu
Error message
`rotation_point` must be one of {'xy', 'center', (number, number)}. What it means
Rectangle accepts a rotation_point ('xy' by default) that fixes the pivot used when rotating the rectangle via its angle attribute: allowed values are the strings 'center' and 'xy' or a tuple of two Real numbers. The setter validates this union and raises ValueError("`rotation_point` must be one of {'xy', 'center', (number, number)}.") for anything else. Note the type strictness: a list [x, y] or a numpy array is rejected because only tuple passes the isinstance check, and 1-element or 3-element tuples fail too.
Source
Thrown at lib/matplotlib/patches.py:916
.scale(1, self._aspect_ratio_correction) \
.rotate_deg(self.angle) \
.scale(1, 1 / self._aspect_ratio_correction) \
.translate(*rotation_point)
@property
def rotation_point(self):
"""The rotation point of the patch."""
return self._rotation_point
@rotation_point.setter
def rotation_point(self, value):
if value in ['center', 'xy'] or (
isinstance(value, tuple) and len(value) == 2 and
isinstance(value[0], Real) and isinstance(value[1], Real)
):
self._rotation_point = value
else:
raise ValueError("`rotation_point` must be one of "
"{'xy', 'center', (number, number)}.")
def get_x(self):
"""Return the left coordinate of the rectangle."""
return self._x0
def get_y(self):
"""Return the bottom coordinate of the rectangle."""
return self._y0
def get_xy(self):
"""Return the left and bottom coords of the rectangle as a tuple."""
return self._x0, self._y0
def get_corners(self):
"""
Return the corners of the rectangle, moving anti-clockwise from
(x0, y0).View on GitHub (pinned to b379c1b69e)
Solutions
- Use 'center' or 'xy' for named pivots.
- For a custom pivot pass a 2-tuple of numbers: rect.rotation_point = (0.5, 0.5).
- Coerce dynamic inputs: tuple(map(float, value)) before assignment.
- Compute the wanted pivot from the rectangle bbox: (rect.get_x() + w/2, rect.get_y() + h/2) reproduces 'center' if you need numeric control.
Example fix
# before rect = Rectangle((0, 0), 2, 1, angle=30, rotation_point=[0.5, 0.5]) # after rect = Rectangle((0, 0), 2, 1, angle=30, rotation_point=(1.0, 0.5)) # or a named pivot: rotation_point='center'
Defensive patterns
Strategy: type-guard
Validate before calling
from numbers import Real
def coerce_rotation_point(v):
if isinstance(v, (list, np.ndarray)):
v = tuple(v)
if not (v in ('xy', 'center') or (
isinstance(v, tuple) and len(v) == 2
and all(isinstance(c, Real) for c in v))):
raise ValueError(f'bad rotation_point: {v!r}')
return v Type guard
def is_valid_rotation_point(v) -> bool:
from numbers import Real
return v in ('xy', 'center') or (
isinstance(v, tuple) and len(v) == 2
and isinstance(v[0], Real) and isinstance(v[1], Real)) Prevention
- Convert JSON/config lists to tuples before assigning rotation_point.
- Only 'xy', 'center', or a 2-number tuple are valid — lists and arrays are not.
- Compute numeric pivots from rect.get_x()/get_y() + size when you need custom anchors.
When it happens
Trigger: rect.rotation_point = 'left' or 'top' (not supported); rect.rotation_point = [0.5, 0.5] (list, not tuple); rect.rotation_point = (0.5,) (wrong length); Rectangle(..., rotation_point='center bottom') copied from other APIs.
Common situations: Users expecting anchor strings like those of AnchoredOffsetbox ('upper left'); passing JSON-decoded coordinates (always lists); interpolating a pivot from config as a list instead of a tuple; interactive rectangle-rotation tools (e.g. widgets.RectangleSelector ecosystem) setting arbitrary pivots.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- shade must be between 0 and 1.
- Got unknown shape: {self._shape!r}
- Parameter 'r' must be one or two floats.
- rotation must be 'vertical', 'horizontal' or a number, not {
- str(_cpe)
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/9fa00d7cea1a4dc6.
Report an issue: GitHub.