How to plot a curved interpolation of a line with non-increasing X

I have a line of x/y points, but the line at some point goes “straight up” (i.e. the x values don’t increase, but the y values do).

How can I plot a curve of this line?

I tried using various methods, including CubicSpline, which raised this error:

# ValueError: `x` must be strictly increasing sequence.

The line I want to plot is the red line, which I added with GIMP. It was not plotted by matplotlib.

learn-curve

"""How can I curve this non-increasing x line?."""

import numpy as np
import matplotlib.pyplot as plt

from scipy.interpolate import CubicSpline  # type: ignore

# fmt: off
line = np.array( [ [0, 6], [1, 5], [2, 4], [3, 3], [4, 2], [4, 1], [4, 0], ])
# fmt: on

x = line[:, 0]
y = line[:, 1]

# Plotting the original points
plt.plot(x, y, "o", label="points", color="blue")
plt.plot(x, y, "-", label="straight line", color="orange")

failure_exn = None

# Upscaling and executing cubic spline fails due to
# ValueError: `x` must be strictly increasing sequence.
try:
    upscale_factor = 64
    xnew = np.linspace(np.min(x), np.max(x), num=(len(x) * upscale_factor), endpoint=True)
    spl = CubicSpline(x, y)
    ynew = spl(xnew)
    plt.plot(xnew, ynew, "-", label="spline", color="red")
except ValueError as e:
    failure_exn = e

plt.legend()
plt.suptitle("How can I curve this line?")
plt.title("ValueError: `x` must be strictly increasing sequence.", fontsize="medium")
plt.xlabel("x")
plt.ylabel("y")
plt.savefig("learn-curve.png")

# Throw after plotting original points
if failure_exn:
    raise failure_exn

This is more of a scipy question than Matplotlib as

import scipy
from scipy.interpolate import CubicSpline  # type: ignore
import numpy as np

line = np.array( [ [0, 6], [1, 5], [2, 4], [3, 3], [4, 2], [4, 1], [4, 0], ])
x = line[:, 0]
y = line[:, 1]
spl = CubicSpline(x, y)

is enough to get the error. As per the CublicSpline docs

Interpolate data with a piecewise cubic polynomial which is twice continuously differentiable

which if you have repeated x values your function is not differentiable (nor a proper single value function in the math sense).

I suggest you look at the “Parametric Spline Curve” section of 1-D interpolation — SciPy v1.13.1 Manual and you treat this data not as y = f(x), but as x, y = k(u) where u is some “hidden” parametric value.

1 Like