matplotlib/matplotlib · error · ValueError

positions must be one-dimensional

Error message

positions must be one-dimensional

What it means

EventCollection (the artist behind ax.eventplot) stores each event as a short segment at a position along one axis; set_positions requires a flat, 1-dimensional sequence of positions. Any nested list or 2D array (np.ndim != 1) raises ValueError before the segments are built.

Source

Thrown at lib/matplotlib/collections.py:1969

        self._is_horizontal = True  # Initial value, may be switched below.
        self._linelength = linelength
        self._lineoffset = lineoffset
        self.set_orientation(orientation)
        self.set_positions(positions)

    def get_positions(self):
        """
        Return an array containing the floating-point values of the positions.
        """
        pos = 0 if self.is_horizontal() else 1
        return [segment[0, pos] for segment in self.get_segments()]

    def set_positions(self, positions):
        """Set the positions of the events."""
        if positions is None:
            positions = []
        if np.ndim(positions) != 1:
            raise ValueError('positions must be one-dimensional')
        lineoffset = self.get_lineoffset()
        linelength = self.get_linelength()
        pos_idx = 0 if self.is_horizontal() else 1
        segments = np.empty((len(positions), 2, 2))
        segments[:, :, pos_idx] = np.sort(positions)[:, None]
        segments[:, 0, 1 - pos_idx] = lineoffset + linelength / 2
        segments[:, 1, 1 - pos_idx] = lineoffset - linelength / 2
        self.set_segments(segments)

    def add_positions(self, position):
        """Add one or more events at the specified positions."""
        if position is None or (hasattr(position, 'len') and
                                len(position) == 0):
            return
        positions = self.get_positions()
        positions = np.hstack([positions, np.asanyarray(position)])
        self.set_positions(positions)
    extend_positions = append_positions = add_positions

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Flatten first: ev.set_positions(np.ravel(positions))
  2. Pass a flat Python list or 1D ndarray of positions
  3. For multi-row eventplots, keep a list of 1D arrays at the eventplot() call level rather than nesting into set_positions

Example fix

# before
ev = EventCollection([[0.1], [0.4], [0.9]])  # each wrapped in a list

# after
ev = EventCollection([0.1, 0.4, 0.9])
# or: ev.set_positions(np.ravel(positions))
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def set_positions_1d(ev, positions):
    pos = np.asarray(positions)
    if pos.ndim != 1:
        pos = pos.ravel()
    ev.set_positions(pos)

set_positions_1d(event_collection, nested_positions)

Type guard

import numpy as np

def is_flat_positions(p) -> bool:
    return np.ndim(p) == 1

Prevention

When it happens

Trigger: EventCollection([[1, 2], [3, 4]]); ev.set_positions(np.array([[0.1], [0.5]])) (an (N,1) column array); passing per-event [pos, weight] pairs.

Common situations: Positions arriving from grouped/aggregated data as a list of single-element lists; column vectors from pandas or sklearn; converting event data that was stored nested.

Related errors


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