matplotlib/matplotlib · error · ValueError

Cannot draw a line through two identical points (x={(x1, x2)

Error message

Cannot draw a line through two identical points (x={(x1, x2)}, y={(y1, y2)})

What it means

When an AxLine defined by two points is drawn, get_transform maps both points to display space to compute the direction. If the transformed points coincide (dx == 0 and dy == 0) the direction is undefined, so a ValueError is raised at draw time, not at the axline() call. Distinct data-space points can still collapse under a nonlinear axis transform: on log scales all non-positive coordinates map to the same clamped value.

Source

Thrown at lib/matplotlib/lines.py:1559

                "Exactly one of 'xy2' and 'slope' must be given")

        self._slope = slope
        self._xy1 = xy1
        self._xy2 = xy2

    def get_transform(self):
        ax = self.axes
        points_transform = self._transform - ax.transData + ax.transScale

        if self._xy2 is not None:
            # two points were given
            (x1, y1), (x2, y2) = \
                points_transform.transform([self._xy1, self._xy2])
            dx = x2 - x1
            dy = y2 - y1
            if dx == 0:
                if dy == 0:
                    raise ValueError(
                        f"Cannot draw a line through two identical points "
                        f"(x={(x1, x2)}, y={(y1, y2)})")
                slope = np.inf
            else:
                slope = dy / dx
        else:
            # one point and a slope were given
            x1, y1 = points_transform.transform(self._xy1)
            slope = self._slope
        (vxlo, vylo), (vxhi, vyhi) = ax.transScale.transform(ax.viewLim)
        # General case: find intersections with view limits in either
        # direction, and draw between the middle two points.
        if slope == 0:
            start = vxlo, y1
            stop = vxhi, y1
        elif np.isinf(slope):
            start = x1, vylo
            stop = x1, vyhi

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Make the two points differ before plotting: if xy1 == xy2, perturb xy2 or switch to the slope form
  2. On log axes choose strictly positive, well-separated anchor points
  3. For vertical/horizontal references on log axes prefer ax.axvline/axhline, which are transform-safe
  4. Wrap the first draw in try/except so a degenerate line can be skipped or replaced instead of killing the whole figure

Example fix

# before
ax.set_xscale('log')
ax.axline((0, 0), xy2=(0, 1))  # both x collapse on log scale -> ValueError at draw
# after
ax.axline((1, 1), xy2=(2, 2))  # positive, distinct points
Defensive patterns

Strategy: try-catch

Validate before calling

if tuple(xy1) == tuple(xy2):
    raise ValueError('axline anchor points must differ')
if ax.get_xscale() == 'log' or ax.get_yscale() == 'log':
    assert all(v > 0 for p in (xy1, xy2) for v in p), 'log-scale axline points must be positive'
line = ax.axline(xy1, xy2=xy2)

Try / catch

try:
    line = ax.axline(xy1, xy2=xy2)
    fig.canvas.draw()  # force get_transform now, not at savefig time
except ValueError as err:
    if 'identical points' in str(err):
        line = None  # skip or replace the degenerate line
    else:
        raise

Prevention

When it happens

Trigger: ax.axline((1, 1), xy2=(1, 1)) with literally identical points; ax.set_xscale('log') followed by ax.axline((0, 0), xy2=(0, 1)) where both x values collapse under the log transform; data-driven xy2 (min/max pairs) that degenerate to a single point on constant series.

Common situations: Fit-through-origin or reference lines on log axes that contain zero or negative data; the error surfacing later at fig.canvas.draw(), plt.show(), or savefig instead of at the axline call; interactive data where xy2 occasionally equals xy1.

Related errors


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