I wanted to decompose the following signal, a numpy array:
I'm currently using the seasonal_decompose function from statsmodels.tsa.seasonal: https://www.statsmodels.org/dev/generated/statsmodels.tsa.seasonal.seasonal_decompose.html
My code:
myPeriod = 60
decompose_result_mult = seasonal_decompose(mySignal,
model="additive",period=myPeriod)
trend = decompose_result_mult.trend
seasonal = decompose_result_mult.seasonal
residual = decompose_result_mult.resid
moyen=trend
tempo=residual+seasonal
And what I get when I plot the moyen (orange) and tempo (green) variables:
The default value used for the trend is the mean value of the signal, and the tempo variable can then be negative. Is it possible to achieve the same thing but by taking the "minimal value" instead of the "mean value" of the function? Which would lead to the tempo variable being only positive. To illustrate what I mean it would be to use something like the following red line as the "trend" data, and get the corresponding tempo data:
How can I achieve this (I did not find how to change the way seasonal_decompose works nor how to achieve this with other functions)?
You can use the "rolling ball" algorithm, as implemented in, e.g., scikit-image (see here). An example (with some fake data that looks a bit like yours) would be:
import numpy as np
from matplotlib import pyplot as plt
from scipy.signal import butter, lfilter
from skimage import restoration
# some fake data (low pass filtered to look a bit more like the data in the original question)
t = np.linspace(0, 10, 500)
x = np.random.randn(len(t))
b, a = butter(3, 0.25, btype="low")
xf = lfilter(b, a, x)
xf -= xf[0]
xf += 3 * t
fig, ax = plt.subplots()
ax.plot(t, xf, label="data")
# get "background" using rolling ball algorithm
background = restoration.rolling_ball(xf, radius=50)
ax.plot(t, background, label="background")
ax.plot(t, xf - background, label="residual")
ax.legend()
You can play about with the radius
value as required for your problem.