2
votes

I am confused on how this function is supposed to work. I am trying to fit a line of best fit for the data sets of xdata and ydata. This code produces errors, but I do not understand how the curve_fit function is supposed to work or if I have used the right terms for what I wanted to do. xdata and ydata plotted on a graph produces a curved patter, going up, and then dropping down. Any help much appreciated.

#define xdata dnd ydata 
xdata = np.array([-2,-1.64,-1.33,-0.7,0,0.45,1.2,1.64,2.32,2.9])
ydata = np.array([0.699369,0.700462,0.695354,1.03905,1.97389,2.41143,1.91091,0.919576,-0.730975,-
1.42001]) 



# get the curve fit funtion 
from scipy.optimize import curve_fit
def func(xdata, p1, p2):
    return p1*np.cos(p2*xdata) + p2*np.sin(p1*xdata)


popt, pcov = curve_fit(func, xdata, ydata)


#plot code for data points 
plot.plot(xdata,ydata,"bo",label="Xdata and Ydata")
plot.plot(popt,pcov,"r--",label="Curve of Best Fit")
plot.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plot.show()

This currently produces a straight line which is not the curve of best fit for the data. I am trying to mirror the data pattern as best as possible, and currently I am nowhere close.

2
What is x in the function? Do you mean xdata? - Leb
I meant for it to be xdata (I think) but I just changed it and I am now getting the error "only length-1 arrays can be converted to Python scalars" - mmb_rach
Because you need np.cos and np.sin instead. - Leb
You're plotting the covariance matrix as function of the best-fit parameters. You may need to read up on the output of curve_fit: you'll need to create your best-fit curve yourself, using popt as input. @eph's answer has this clearest. - user707650

2 Answers

2
votes

What you were missing:

  1. As I said in my comments you needed np.cos and np.sin. The reason for that is because xdata and ydata are numpy arrays of (10,) shape. Therefore Python can't recognize that, it needs to be (10,1)
  2. You need to define a linspace for the data, it's called xfine in the below example

Here's a working example:

import numpy as np
import matplotlib.pyplot as qt
from scipy.optimize import curve_fit

#define xdata dnd ydata 
xdata = np.array([-2,-1.64,-1.33,-0.7,0,0.45,1.2,1.64,2.32,2.9])
ydata = np.array([0.699369,0.700462,0.695354,1.03905,1.97389,2.41143,1.91091,0.919576,-0.730975,-
1.42001]) 

def func(xdata, p1, p2):
    return p1*np.cos(p2*xdata) + p2*np.sin(p1*xdata)

xfine = np.linspace(xdata.min(), xdata.max(), 100)

popt, pcov = curve_fit(func, xdata, ydata)

plt.plot(xdata, ydata, '.');
plt.plot(xfine, func(xfine, popt[0], popt[1]),'r-')

enter image description here

1
votes

You need to use numpy.cos instead of math.cos to handle vectors:

def func(xdata, p1, p2):
    return p1*np.cos(p2*xdata) + p2*np.sin(p1*xdata)

And you need to generate fit curve like this:

xfit = np.linspace(xdata[0], xdata[-1], 100)
yfit = func(xfit, *popt)
plt.plot(xdata, ydata)
plt.plot(xfit, yfit)
plt.show()