1

enter image description here

My Question

I tried regression using curve_fit function from scipy module, and now I am getting a scattered kind of plot, I can't figure it out, Why I am getting a scattered plot here ?

My Code

def scipyFunction(x,y):
    plot(x, y, 'o', label='Original data', markersize=10)

    x = [float(xn) for xn in x] #every element (xn) in x becomes a float
    y = [float(yn) for yn in y] #every element (yn) in y becomes a float
    x = np.array(x) #tranform data into numpy array
    y = np.array(y) #transform data into numpy array

    def functionForScipy(x,a,b,c,d):
        return a*x**3 + b*x**2 + c*x + d 

    #make the curve_fit
    popt,pcov = curve_fit(functionForScipy,x,y)

    '''
    The result is :
    popt[0] = a, popt[1] = b, popt[2] = d of the function,
    so f(x) = popt[0]*x**3 + popt[1]*x**2 + popt[2]*x + popt[3].
    '''

    print(popt)

    plt.plot(x, popt[0]*x**3 + popt[1]*x**2 + popt[2]*x + popt[3], label="Fitted Curve")  # same as lin eabove

    plt.legend(loc='upper left')
    plt.show()

x and y plot is like this :

enter image description here

2
  • Are you asking why your green line is not straight but is instead jumping around the place? Commented Aug 12, 2014 at 13:13
  • How do x and y look like? Commented Aug 12, 2014 at 13:23

2 Answers 2

2

I suspect this occurs because the values in your x array are not monotonically increasing (that is to say that the each subsequent number is larger than the last).

You need to sort your x values before you plot them otherwise they will be all over the place, as shown in the example below.

import numpy as np
import matplotlib.pyplot as plt

def func(x):
    return x**2

x = np.array([0, 5, 2, 1, 3, 4])
y = func(x)

plt.plot(x, y, 'b-', label='Unsorted')

x.sort()
y = func(x)

plt.plot(x, y, 'r-', label='Sorted')

plt.legend()

plt.show()

Example

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

Comments

1

Probably your x and y are not sorted.

Don't forget the apply the same sorting you do on x on y as well. To achieve this zip is very handy. You could add the following at the beginning of your function:

comb = zip(x,y)
comb.sort(key=lambda x:x[0])  #sort according to x
x, y = zip(*comb)  #both x and y are sorted now according to x

3 Comments

Thank you so much, just a minor mistake in here zip object cannot be sorted like that, it has to be converted into list, thus comb = list(zip(z,y)), and then apply sort..thanks anyway.. :)
@AkashRana run print type(zip([1,2,3],[2,3,1])) ;)
Just to clarify, from python.org: zip([iterable, ...]) This function returns a list of tuples.

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.