Best fit curve for data

I am working with data on a chart(dataset/pydataset), and am looking to find the best fit curve for the data. Is there a way to do this in Ignition? I wrote a script to generate a best fit line for a set of data points, but curves are way more complicated, and as I’ve found you need to be able to use numpy/scipy to really get the functionality.

Right, we don’t have a built-in function for a best fit curve. You can create one through scripting though.

import math

def F(coeffs, x):
	total = 0.0
	x_factor = 1.0
	for coefficient in coeffs:
		total = total + (x_factor * coefficient)
		x_factor =  x_factor * x
	return total
	
def ErrorSquared(points, coeffs):
	#Return the error squared.
    total = 0.0
    for pt in points:
    	x = pt[0]
    	y = pt[1]
    	dy = y - F(coeffs, x)
        total = total + (dy * dy)
    return total
	
def GaussianElimination(coeffs):
	max_equation = len(coeffs)
	max_coeff = len(coeffs[0])
	for i in range(max_equation):
		#Use equation_coeffs(i, i) to eliminate the ith coefficient in all of the other equations.
		#Find a row with non-zero ith coefficient.
		if coeffs[i][i] == 0:
			for j in range(i + 1, max_equation):
				#See if this one works.
				if coeffs[j][i] <> 0:
					#This one works. Swap equations i and j.
					#This starts at k = i because all
					#coefficients to the left are 0.
					for k in range(i , max_coeff):
						temp = coeffs[i][k]
						coeffs[i][k] = coeffs[j][k]
						coeffs[j][k] = temp
					break

		#Make sure we found an equation with
		#a non-zero ith coefficient.
		coeff_i_i = coeffs[i][i]
		if coeff_i_i == 0:
			#Throw New ArithmeticException(String.Format("There is no unique solution for these points.", coeffs.GetUpperBound(0) - 1))
			print("There is no unique solution for these points.")
			print(coeffs[i])
			break
		else:
			#Normalize the ith equation.
			for j in range(i , max_coeff):
				coeffs[i][j] = coeffs[i][j] / coeff_i_i
	
			#Use this equation value to zero out the other equations' ith coefficients.
			for j in range(max_equation):
				#Skip the ith equation.
				if j <> i:
					#Zero the jth equation's ith coefficient.
					coef_j_i = coeffs[j][i]
					for d in range(max_coeff):
						coeffs[j][d] = coeffs[j][d] - coeffs[i][d] * coef_j_i

	#At this point, the ith equation contains 2 non-zero entries:
	#The ith entry which is 1
	#The last entry coeffs(max_coeff)
	#This means Ai = equation_coef(max_coeff)
	solution = []
	for i in range(max_equation):
		solution.append(coeffs[i][max_coeff - 1])
	#Return the solution values.
	return solution

def FindPolynomialLeastSquaresFit(points, degree):
	#Find the least squares linear fit.
	coeffs = [ [0 for x in range(degree + 2)] for y in range(degree + 1)]
	
	#Calculate the coefficients for the jth equation.
	for j in range(degree + 1):
	
	    #Calculate the constant term for this equation.
		for pt in points:
			x = pt[0]
			y = pt[1]
			coeffs[j][degree + 1] = coeffs[j][degree + 1] - (math.pow(x, j) * y)
			
		#Calculate the other coefficients.
		for a_sub in range(degree + 1):
			#Calculate the dth coefficient.
			coeffs[j][a_sub] = 0
			for pt in points:
				x = pt[0]
				y = pt[1]
				coeffs[j][a_sub] = coeffs[j][a_sub] - math.pow(x, a_sub + j)

	#Solve the equations.
	answer = GaussianElimination(coeffs)

	return answer

degree = 4
points = [ [1278,22669],[2109,34768],[3095,49191],[4087,63718],[5090,78383],[6089,92984],[7008,106420],[8007,121077],[9091,136940],[9944,149442],[10136,152255],[10223,153454],[10314,154348],[10344,154561],[10435,155034],[10446,155097]]

FindPolynomialLeastSquaresFit(points, degree)

3 Likes

Shamelessly stolen from www.vb-helper.com and converted into Python

1 Like

Another (more general) solution would be to use the Apache Commons Math library curve fitting functions which seem to be included with the standard distribution.

Java code based on that lib which should be easy to convert to python can be found here:

1 Like

Testing now, this looks like it will be a pretty useful tool.

Any suggestion on how to get an exponential curve fit instead of a polynomial?