Search code examples
scipycurve-fittingdata-fitting

How to fit a curve to a set of data for same x values?


I have some curves from the lab tests on material. each set of data has different lenghts. i am willing to fit a curve to these data. Lets start with data having same lenght: y1 y2 y3 with same x values.

import numpy as np
import matplotlib.pyplot as plt

def my_function(x,y):
    curve = np.polyfit(x, y, 4)
    poly = np.poly1d(curve)

    new_x = np.arange(x[0],x[-1],1)
    new_y= poly(new_x)

    plt.plot(new_x, new_y)
    plt.scatter(x, y)
    print(poly)
    
x =  [0, 5.25, 10.5, 21, 31.5, 42, 52.5, 63, 73.5, 84, 94.5, 99.75, 105]

y1=[0.2535,0.3552,0.456,0.489,0.5265,0.58384,1.87616,2.87328,2.55184,2.66992,2.8208,3.09632,3.51616]
y2=[0.116112,0.425088,0.582528,0.70192,1.07584,2.41408,3.75232,4.61824,2.55184,2.66992,2.8208,3.09632,3.51616]
y3=[0.389664,1.166368,1.60392,2.05984,2.788,4.02784,5.0184,5.60224,2.55184,2.66992,2.8208,3.09632,3.51616]


ylist = [ y1, y2, y3]

for y in ylist:    
   my_function(x,y)

My final goal is to do this for pairs of y and x, which their lenghts are different from other pairs of data.

what im expecting is like this: enter image description here


Solution

  • I may be misunderstanding your question but nothing in your code presumes that all your y's have to have the same length. This works for me:

    import numpy as np
    import matplotlib.pyplot as plt
    
    def my_function(x,y):
        curve = np.polyfit(x, y, 4)
        poly = np.poly1d(curve)
    
        new_x = np.arange(x[0],x[-1],1)
        new_y= poly(new_x)
    
        plt.plot(new_x, new_y)
        plt.scatter(x, y)
        print(poly)
        
    x1 =  [0, 5.25, 10.5, 21, 31.5, 42, 52.5, 63, 73.5, 84, 94.5, 99.75, 105]
    x2 =  [0, 5.25, 10.5, 21, 31.5, 42, 52.5, 63, 73.5, 84, 94.5, 99.75]
    x3 =  [0, 5.25, 10.5, 21, 31.5, 42, 52.5, 63, 73.5, 84, 94.5]
    
    y1=[0.2535,0.3552,0.456,0.489,0.5265,0.58384,1.87616,2.87328,2.55184,2.66992,2.8208,3.09632,3.51616]
    y2=[0.116112,0.425088,0.582528,0.70192,1.07584,2.41408,3.75232,4.61824,2.55184,2.66992,2.8208,3.09632]
    y3=[0.389664,1.166368,1.60392,2.05984,2.788,4.02784,5.0184,5.60224,2.55184,2.66992,2.8208]
    
    
    ylist = [ y1, y2, y3]
    xlist = [ x1, x2, x3]
    
    for x, y in zip(xlist, ylist):
        my_function(x,y)
    

    Edit: From the clarification in the comment

    the goal is to fit one curve for all three y1 y2 y3 with their corresponding x1 x2 x3 curves

    So all points in the curves defined by (x1, y1), (x2, y2), (x3, y3), ... should be fit to a single polynomial.

    This can be done by simply concatenating the vectors containing the data:

    x_tot = np.concatenate((x1, x2, x3))
    y_tot = np.concatenate((y1, y2, y3))
    my_function(x_tot,y_tot)
    

    Which results in: fit plot

    Note that the (x, y) arrays don't have to be the same length. In case that y1, y2, ..., share the same x, the concatenation should be x_tot = np.concatenate((x, x, x))