In [1]:
import numpy as np
import matplotlib.pylab as plt
In [2]:
# make up some dummy data
x = np.arange(0,20,0.2)
y1 = 2*x+5 + np.random.normal(loc=0,scale=2,size=len(x))
y2 = 3*x+2 + np.random.normal(loc=0,scale=4,size=len(x))
y3 = 2.5*x+8 + np.random.normal(loc=0,scale=2,size=len(x))
y4 = 1.5*x+1 + np.random.normal(loc=0,scale=2,size=len(x)) 

You could make four separate plots of the data, each with a fit¶

In [3]:
# load the different y values into python list that contains tuples with the following info:
# (value,label)
yinfo = [(y1,'y1 values'),
         (y2,'y2 values'),
         (y3,'y3 values'),
         (y4,'y4 values')]

for ydata,ylabel in yinfo:
    
    plt.figure(figsize=(6,6))
    plt.scatter(x,ydata,s=5)
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.xlim(0,20)
    plt.ylim(0,80)
    plt.title(ylabel)
    
    # fit a line t
    print('Fitting dataset {}:'.format(ylabel))
    coeff,cov=np.polyfit(x,ydata,1,cov=True)
    coeff_err = np.sqrt(np.diag(cov))
    print('       slope = {:.3f} +/- {:.3f}'.format(coeff[0],coeff_err[0]))
    print('   intercept = {:.3f} +/- {:.3f}'.format(coeff[1],coeff_err[1]))
    polynomial=np.poly1d(coeff)
    print('     scatter = {:.3f}'.format(np.std(ydata-polynomial(x))))
    print('===================')
    xfit=np.linspace(np.min(x),np.max(x),100)
    plt.plot(xfit,polynomial(xfit),color='green',lw=3)
    
Fitting dataset y1 values:
       slope = 1.951 +/- 0.036
   intercept = 5.047 +/- 0.418
     scatter = 2.084
===================
Fitting dataset y2 values:
       slope = 3.023 +/- 0.062
   intercept = 2.113 +/- 0.707
     scatter = 3.527
===================
Fitting dataset y3 values:
       slope = 2.434 +/- 0.034
   intercept = 8.002 +/- 0.395
     scatter = 1.970
===================
Fitting dataset y4 values:
       slope = 1.500 +/- 0.036
   intercept = 1.271 +/- 0.408
     scatter = 2.036
===================

or you could make a single plot with four subpanels¶

In [4]:
Fig,((y1plot,y2plot),(y3plot,y4plot))=plt.subplots(2,2,figsize=(10,10))

# load the different y values into python list that contains tuples with the following info:
# (value,label,subplot_name)
yinfo = [(y1,'y1 values',y1plot),
         (y2,'y2 values',y2plot),
         (y3,'y3 values',y3plot),
         (y4,'y4 values',y4plot)]
    
# loop over the tuples containing the different y value info
for ydata,ylabel,yplot in yinfo:
    
    # plot the data, all the plots will have the same limits and correct labels
    yplot.scatter(x,ydata,s=5)
    yplot.set_xlim(0,20)
    yplot.set_ylim(0,80)
    yplot.set_xlabel('X')
    yplot.set_ylabel(ylabel)
    
    # fit a line to each dataset
    print('Fitting dataset {}:'.format(ylabel))
    coeff,cov=np.polyfit(x,ydata,1,cov=True)
    coeff_err = np.sqrt(np.diag(cov))
    print('       slope = {:.3f} +/- {:.3f}'.format(coeff[0],coeff_err[0]))
    print('   intercept = {:.3f} +/- {:.3f}'.format(coeff[1],coeff_err[1]))
    polynomial=np.poly1d(coeff)
    print('     scatter = {:.3f}'.format(np.std(ydata-polynomial(x))))
    print('===================')
    xfit=np.linspace(np.min(x),np.max(x),100)
    yplot.plot(xfit,polynomial(xfit),color='green',lw=3)

    
Fig.tight_layout()
Fitting dataset y1 values:
       slope = 1.951 +/- 0.036
   intercept = 5.047 +/- 0.418
     scatter = 2.084
===================
Fitting dataset y2 values:
       slope = 3.023 +/- 0.062
   intercept = 2.113 +/- 0.707
     scatter = 3.527
===================
Fitting dataset y3 values:
       slope = 2.434 +/- 0.034
   intercept = 8.002 +/- 0.395
     scatter = 1.970
===================
Fitting dataset y4 values:
       slope = 1.500 +/- 0.036
   intercept = 1.271 +/- 0.408
     scatter = 2.036
===================

or you could make a single plot with all the different datasets overlaid¶

In [5]:
Fig,Allplot=plt.subplots(1,1,figsize=(10,10))

# load the different y values into python list that contains tuples with the following info:
# (value,label,plotcolor)
yinfo = [(y1,'y1 values','blue'),
         (y2,'y2 values','green'),
         (y3,'y3 values','red'),
         (y4,'y4 values','black')]
    
# loop over the tuples containing the different y value info
for ydata,ylabel,plotcolor in yinfo:
    
    # plot the data, all the plots will have the same limits and correct labels
    Allplot.scatter(x,ydata,s=5,color=plotcolor,label=ylabel)
    
    # fit a line to each dataset
    print('Fitting dataset {}:'.format(ylabel))
    coeff,cov=np.polyfit(x,ydata,1,cov=True)
    coeff_err = np.sqrt(np.diag(cov))
    print('       slope = {:.3f} +/- {:.3f}'.format(coeff[0],coeff_err[0]))
    print('   intercept = {:.3f} +/- {:.3f}'.format(coeff[1],coeff_err[1]))
    polynomial=np.poly1d(coeff)
    print('     scatter = {:.3f}'.format(np.std(ydata-polynomial(x))))
    print('===================')
    xfit=np.linspace(np.min(x),np.max(x),100)
    Allplot.plot(xfit,polynomial(xfit),color=plotcolor,lw=3)

# since I'm plotting everything on the same plot, 
# I just set the plot parameters after the loop is finished

Allplot.set_xlim(0,20)
Allplot.set_ylim(0,80)
Allplot.set_xlabel('X')
Allplot.set_ylabel('Y values')
Allplot.legend()    

Fig.tight_layout()
Fitting dataset y1 values:
       slope = 1.951 +/- 0.036
   intercept = 5.047 +/- 0.418
     scatter = 2.084
===================
Fitting dataset y2 values:
       slope = 3.023 +/- 0.062
   intercept = 2.113 +/- 0.707
     scatter = 3.527
===================
Fitting dataset y3 values:
       slope = 2.434 +/- 0.034
   intercept = 8.002 +/- 0.395
     scatter = 1.970
===================
Fitting dataset y4 values:
       slope = 1.500 +/- 0.036
   intercept = 1.271 +/- 0.408
     scatter = 2.036
===================
In [ ]: