3

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.

4
  • What is x in the function? Do you mean xdata? Commented Dec 4, 2015 at 1:07
  • 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" Commented Dec 4, 2015 at 1:10
  • Because you need np.cos and np.sin instead. Commented Dec 4, 2015 at 1:13
  • 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. Commented Dec 4, 2015 at 1:24

2 Answers 2

3

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

Sign up to request clarification or add additional context in comments.

Comments

1

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()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.