Constrained circular interpolation in python
My question is similar to the question here . To put it simply, I have a time series angle data that is constrained between [0, 360]. I need to calculate the iteration between dimensions. I am currently using scipy.interpolate.interp1d . To clarify my question, here is an example,
import numpy as np
from scipy import interpolate
data = np.array([[0, 2, 4], [1, 359, 1]]) # first row time index, second row angle measurements
f = interpolate.interp1d(data[0, :], data[1, :], kind='linear', bounds_error=False, fill_value=None)
f([1, 3])
this will result in [180., 180.]. However, between time 2 and time 4, the angle changed from 359 to 1, that is, only 2 degrees, and the interpolated value in 3 should have been 0. The angles change in a counterclockwise direction over time.
Finally, my question is as follows,
Is there any standard module I can use to achieve this goal?
Just because I want to avoid custom methods as much as possible!
source to share
Just add a 360 Β° padding every time you find there is a jump and go back to the first 360 degrees using the modulo operation. For example:
In [1]: import numpy as np
In [2]: from scipy import interpolate
In [3]: data = np.array([[0, 2, 4, 6, 8], [1, 179, 211, 359, 1]])
In [4]: complement360 = np.rad2deg(np.unwrap(np.deg2rad(data[1])))
In [5]: complement360
Out[5]: array([ 1., 179., 211., 359., 361.])
In [6]: f = interpolate.interp1d(data[0], complement360, kind='linear', bounds_error=False, fill_value=None)
In [7]: f(np.arange(9))
Out[7]: array([ 1., 90., 179., 195., 211., 285., 359., 360., 361.])
In [8]: f(np.arange(9))%360
Out[8]: array([ 1., 90., 179., 195., 211., 285., 359., 0., 1.])
Note. I've added a few extra values ββhere, since otherwise there is no realistic way to np.unwrap
know in which direction the angle is increasing, and this is probably also how you know it is increasing in this way (the difference between successive values ββis less than 180 Β° if there is no actual break).
If you do have data from which angular jumps more than 180 Β° between two successive elements, but you know the direction the angles change (like CCW) and that it changes monotonically, then you might find it like this:
In [31]: data = np.array([1, 359, 1, 60, 359, 177, 2]) # mock-data
In [32]: jumps = np.diff(data)<0 # assumptions: angle increases stricly monotonously CCW
In [33]: np.hstack((data[0], data[1:] + np.cumsum(np.sign(d)<0)*360))
Out[33]: array([ 1, 359, 361, 420, 719, 897, 1082])
source to share
As of version 1.10.0 numpy.interp takes the period keyword: http://docs.scipy.org/doc/numpy/reference/generated/numpy.interp.html
source to share