matplotlib/matplotlib · error · TypeError

Cannot pass both positional and keyword arguments for x and/

Error message

Cannot pass both positional and keyword arguments for x and/or y.

What it means

Axes.margins() accepts margins either positionally (one value for all axes, or one value per axis) or through the x=/y= keyword arguments, but not both at once. Supplying positional margins together with x or y is ambiguous about which value wins, so matplotlib raises this TypeError before touching any state.

Source

Thrown at lib/matplotlib/axes/_base.py:2923

        -------
        xmargin, ymargin : float

        Notes
        -----
        If a previously used Axes method such as :meth:`pcolor` has set
        `~.Axes.use_sticky_edges` to `True`, only the limits not set by
        the "sticky artists" will be modified. To force all
        margins to be set, set `~.Axes.use_sticky_edges` to `False`
        before calling :meth:`margins`.

        See Also
        --------
        :ref:`autoscale_margins`
        .Axes.set_xmargin, .Axes.set_ymargin
        """

        if margins and (x is not None or y is not None):
            raise TypeError('Cannot pass both positional and keyword '
                            'arguments for x and/or y.')
        elif len(margins) == 1:
            x = y = margins[0]
        elif len(margins) == 2:
            x, y = margins
        elif margins:
            raise TypeError('Must pass a single positional argument for all '
                            'margins, or one for each margin (x, y).')

        if x is None and y is None:
            if tight is not True:
                _api.warn_external(f'ignoring tight={tight!r} in get mode')
            return self._xmargin, self._ymargin

        if tight is not None:
            self._tight = tight
        if x is not None:
            self.set_xmargin(x)

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Choose one convention: drop the keyword arguments and pass all values positionally, or drop the positional values and pass x=/y= only.
  2. For partial updates, use the keyword form only, e.g. ax.margins(x=0.1) leaves y untouched.
  3. In wrappers, pop or merge margins before forwarding a single canonical form.

Example fix

# before
ax.margins(0.2, x=0.1)

# after
ax.margins(x=0.1)
Defensive patterns

Strategy: validation

Validate before calling

if pos_margins and (x is not None or y is not None):
    pos_margins = ()  # let keywords win, or raise your own error
ax.margins(*pos_margins, x=x, y=y)

Prevention

When it happens

Trigger: ax.margins(0.2, x=0.1); ax.margins(0.1, 0.2, y=0.3); wrapper functions that forward *args while also injecting explicit x=/y= keywords.

Common situations: Incrementally editing an existing positional call by appending keyword overrides; generic plotting helpers that merge user kwargs with their own margins settings; copy-paste between the two calling conventions.

Related errors


AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21). Data as JSON: /api/errors/f752882d8adc949b. Report an issue: GitHub.