'The graph and the values of the data fitted formula for my data are wrong and I don't know how to fix them
Problem in data fitting
Hi everyone, I'm quite new in Python and this is the first time I write on Stack Overflow. I've got a problem in fitting the data. With this code I would like to demonstrate a correlation between speed and heart rate in rowing. My code doesn't work properly in fact if i put the results in exponentialdata = exponential(x_data, ..., ..., ...)
the graph it has moved upwards by 150 units.
Also if I put the data that I estimated manually knowing a little of exponential proprieties the graph didn't fit so well the data (I send you herewith a picture). I think that the first two value calculated are correct or very close but the third should be around 5.2.
Maybe someone has an idea for a better equation for this data.
Graph with values calculated by the code
This is the set of data that I used:
Pace (seconds);Stroke Rate;Heart Rate;Speed (m/s)
97;26;157;5.15
94.9;28;165;5.27
95.8;26;170;5.22
92.5;30;170;5.41
94;28;173;5.32
90.6;32;173;5.52
94.6;27;176;5.29
91.7;30;177;5.45
92;29;178;5.43
90;32;180;5.56
89.8;31;182;5.57
87.9;32;184;5.69
Is there anyone of you that can help me with these problems? I don't know how to do it, I've been stuck here for days. Thanks in advance and I hope I was clear enough in explaining my problems
This is my code:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import csv
## PACE-BPM ##
# Import CSV Data
with open("new 1 minuto 26-28-30-32.csv","r") as i:
rawdata = list(csv.reader(i,delimiter = ";"))
exampledata = np.array(rawdata[1:], dtype=np.float)
x_data = exampledata[:,2]
y_data = exampledata[:,3]
# Plot the Data
plt.figure(2,dpi=120)
plt.plot(x_data,y_data, 'o')
plt.title("Example Data")
plt.xlabel(rawdata[0][2])
plt.ylabel(rawdata[0][3])
#Define Function
def exponential(x, a, b, c):
return a * np.exp(x-b) + c
#Evaluate and Plot Function
exponentialdata = exponential(x_data, 155, 188, 5.2)
plt.plot(x_data, exponentialdata, 'ro--', label="Model")
plt.legend()
#Curve fit data to model
popt, pcov = curve_fit(exponential, x_data, y_data, bounds=(155,188))
perr = np.sqrt(np.diag(pcov))
fit_a = popt[0]
fit_b = popt[1]
fit_c = popt[2]
print(fit_a)
print(fit_b)
print(fit_c)
##########
# Show the plot
plt.show()
Solution 1:[1]
Basically your model is not well chosen. As a * exp(x -b) = a * exp(-b ) * exp(x)
which is equivalent to a' exp(x)
. You need at least a a * exp( b * x ) + c
.
With this I get a decent fit.
This is how mine is working:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import csv
exampledata = np.array([
97, 26, 157, 5.15,
94.9, 28, 165, 5.27,
95.8, 26, 170, 5.22,
92.5, 30, 170, 5.41,
94, 28, 173, 5.32,
90.6, 32, 173, 5.52,
94.6, 27, 176, 5.29,
91.7, 30, 177, 5.45,
92, 29, 178, 5.43,
90, 32, 180, 5.56,
89.8, 31, 182, 5.57,
87.9, 32, 184, 5.69
]).reshape( -1, 4)
print( exampledata )
#Define Function
def exponential(x, a, b, c):
return a * np.exp( x * b ) + c
x_data = exampledata[:,2]
y_data = exampledata[:,3]
# Plot the Data
fig = plt.figure( )
ax = fig.add_subplot( 1, 1, 1 )
ax.plot(x_data,y_data, 'o')
ax.set_title("Example Data")
#Evaluate and Plot Function
exponentialdata = exponential(x_data, 1.6e-6, 0.05,5.0)
plt.plot(x_data, exponentialdata, label="guess")
#Curve fit data to model
popt, pcov = curve_fit(exponential, x_data, y_data, p0=(1e-6, 0.01,4.2),maxfev=1500)
ax.plot( x_data, exponential( x_data, *popt ), 'ro--', label="Model")
perr = np.sqrt(np.diag(pcov))
plt.legend()
fit_a = popt[0]
fit_b = popt[1]
fit_c = popt[2]
print(fit_a)
print(fit_b)
print(fit_c)
##########
# Show the plot
plt.show()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |