Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interpolate without having negative values in python

I've been trying to create a smooth line from these values but I can't have negative values in my result. So far all the methods I tried do give negative values. Would love some help.

import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline
import numpy as np
y = np.asarray([0,5,80,10,1,10,40,30,80,5,0])
x = np.arange(len(y))

plt.plot(x, y, 'r', ms=5)
spl = UnivariateSpline(x, y)
xs = np.linspace(0,len(y)-1, 1000)
spl.set_smoothing_factor(2)

plt.plot(xs, spl(xs), 'g', lw=3)
plt.show()

enter image description here

like image 492
OMRY VOLK Avatar asked Oct 16 '16 16:10

OMRY VOLK


People also ask

What is spline interpolation Python?

Interpolation is a method of estimating unknown data points in a given dataset range. Discovering new values between two data points makes the curve smoother. Spline interpolation is a type of piecewise polynomial interpolation method.

What is Python interpolate?

Introduction. Interpolation is a technique in Python used to estimate unknown data points between two known data points. Interpolation is mostly used to impute missing values in the dataframe or series while preprocessing data.


2 Answers

Spline fitting is known to overshoot. You seem to be looking for one of the so-called monotonic interpolators. For instance,

In [10]: from scipy.interpolate import pchip

In [11]: pch = pchip(x, y)

produces

In [12]: xx = np.linspace(x[0], x[-1], 101)

In [13]: plt.plot(x, y, 'ro', label='points')
Out[13]: [<matplotlib.lines.Line2D at 0x7fce0a7fe390>]

In [14]: plt.plot(xx, pch(xx), 'g-', label='pchip')
Out[14]: [<matplotlib.lines.Line2D at 0x7fce0a834b10>]

enter image description here

like image 157
ev-br Avatar answered Nov 15 '22 04:11

ev-br


This does it, albeit in some sections better than others.

import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline
import numpy as np

y = np.asarray([0,5,80,10,1,10,40,30,80,5,0])
x = np.arange(len(y))

plt.plot(x, y, 'r', ms=5)
spl = UnivariateSpline(x, y)
xs = np.linspace(0,len(y)-1, 1000)
spl.set_smoothing_factor(2)

#new code
ny = spl(xs).clip(0,max(spl(x)))
spl2 = UnivariateSpline(xs, ny)

plt.plot(xs, spl(xs) , 'g', lw=2,label="original")
plt.plot(xs, spl2(xs), 'b', lw=2,label="stack mod")

plt.legend()
plt.show()

enter image description here

like image 25
Dan Steingart Avatar answered Nov 15 '22 05:11

Dan Steingart