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?