matplotlib/matplotlib · error · ValueError

unknown value for which: {which!r}

Error message

unknown value for which: {which!r}

What it means

get_xaxis_transform(which) selects among three transforms for x-axis artists — 'grid' (blended data/axes coordinates), 'tick1' (bottom spine), 'tick2' (top spine); any other value is rejected (lib/matplotlib/axes/_base.py:1009).

Source

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

            This transformation is primarily used by the
            `~matplotlib.axis.Axis` class, and is meant to be
            overridden by new kinds of projections that may need to
            place axis elements in different locations.

        Parameters
        ----------
        which : {'grid', 'tick1', 'tick2'}
        """
        if which == 'grid':
            return self._xaxis_transform
        elif which == 'tick1':
            # for cartesian projection, this is bottom spine
            return self.spines.bottom.get_spine_transform()
        elif which == 'tick2':
            # for cartesian projection, this is top spine
            return self.spines.top.get_spine_transform()
        else:
            raise ValueError(f'unknown value for which: {which!r}')

    def get_xaxis_text1_transform(self, pad_points):
        """
        Returns
        -------
        transform : Transform
            The transform used for drawing x-axis labels, which will add
            *pad_points* of padding (in points) between the axis and the label.
            The x-direction is in data coordinates and the y-direction is in
            axis coordinates
        valign : {'center', 'top', 'bottom', 'baseline', 'center_baseline'}
            The text vertical alignment.
        halign : {'center', 'left', 'right'}
            The text horizontal alignment.

        Notes
        -----
        This transformation is primarily used by the `~matplotlib.axis.Axis`

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Use 'grid', 'tick1' (bottom spine), or 'tick2' (top spine)
  2. For a spine transform directly, call ax.spines['bottom'].get_spine_transform()
  3. For the default blended transform just call ax.get_xaxis_transform() with no argument (defaults to 'grid')

Example fix

# before
tr = ax.get_xaxis_transform(which='bottom')
# after
tr = ax.get_xaxis_transform(which='tick1')  # bottom spine
Defensive patterns

Strategy: validation

Validate before calling

_VALID_WHERE = {'grid', 'tick1', 'tick2'}

assert which in _VALID_WHERE, f'which must be one of {sorted(_VALID_WHERE)}, got {which!r}'
tr = ax.get_xaxis_transform(which=which)

Type guard

def is_valid_which(w) -> bool:
    return w in {'grid', 'tick1', 'tick2'}

Prevention

When it happens

Trigger: ax.get_xaxis_transform(which='bottom'), which='x', which='ticks' — anything outside {'grid', 'tick1', 'tick2'}.

Common situations: Using spine names ('bottom'/'top') instead of tick1/tick2; guessing the API from get_spine_transform or set_position; copied code adjusted for non-cartesian axes.

Related errors


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