I have a problem similar to this previous StackOverflow question. I have a dataset that I would like to fit several piece-wise functions to, then plot the results.
The data is plotted in red below.
To give some context, the y-values represent how many milliseconds a motor takes in order to turn x degrees. I have uploaded the raw values to this Pastebin.
I would now like to fit three functions in a piece-wise manner:
- A polynomial fit for the start of the data, where the motor is accelerating to max speed.
- A linear fit for when max speed is reached.
- A polynomial fit for then the motor is turned off, and decelerates.
So far I have tried to perform a piece-wise fit of two linear functions, using the code shown below. Given what the data look like, I was expecting to see one slope following the data from origin to about ms=550
, then from there a second line running parallel to the x-axis.
However, this is not what I get:
Before I try to perform a piece-wise fit using three functions, I would first like to understand why I get this plot and not what I was expecting.
So my questions are:
- Can anyone explain how to correct my code to make it fit two linear functions?
- How can I expand my code to plot a piece-wise fit using three functions?
The code used to create the plot above is as follows:
from pandas import *
import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize
#Getting data using Pandas
df = read_csv("test_data.csv")
ms = df["ms"].values
degrees = df["Degrees"].values
#A piece wise function taken from the other stackoverflow
def piecewise_linear(x, x0, y0, k1, k2):
return np.piecewise(x, [x < x0], [lambda x:k1*x + y0-k1*x0, lambda x:k2*x + y0-k2*x0])
#Setting linspace and making the fit
x_new = np.linspace(ms[0], ms[-1])
p , e = optimize.curve_fit(piecewise_linear, ms, degrees)
#Plotting data and fit
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x_new, piecewise_linear(x_new, *p), '.', df)
ax.set_ylim([0, 450])
ax.set_xlim([0, 800])