1

I am attempting to build a program that finds (roughly) the equation of a graph given the coordinates of a bunch of points on the graph. The assumption is made that the coordinates given represent the entirety of the graph (ie: the behavior does not change outside the given domain).

I use the simple function below to do this:

#x and y are arrays of the x coordinates and corrosponding y coordinates
def get_equation(x,y):
    degree = 2
    coefs, res, _, _, _ = np.polyfit(x,y,degree, full = True)
    ffit = np.poly1d(coefs)
    print (ffit)
    return ffit

This works reasonably well for the coordinates on the graphs of basic equations such as x^2, but does not work at all for more complicated graphs such as the graph below.

enter image description here

How do I find the equation for more complex graphs like the one above given the coordinates on the graph?

Also, is it possible to figure out what the degree of the graph is, or does that always have to be entered manually?

2 Answers2

1

You need to change the degree on the polynom. For example I created a polynom of the 5th order.

import numpy as np
import matplotlib.pyplot as plt
def SomePoly(k):
    a = [9, 1.5, -12.5, -2.5, 3.5, 1]
    return sum([a[p]*k**p for p in range(len(a))])
x = np.arange(-3,2, 0.1)
y = SomePoly(x)
plt.plot(x, y)

Now see the results for each degree:

for degree in [2,4,5]:
    coefs, res, _, _, _ = np.polyfit(x,y,degree, full = True)
    print(degree, res)

the results:

2 [947.22023682]
4 [683.734662]
5 [8.70566837e-27]
user1889297
  • 464
  • 5
  • 13
1

If the behavior does not change outside the given domain, look into splines and fit those to the domain. This can be done with scipy.interpolate.

Here is an example

 from matplotlib.pyplot import subplots
from numpy import linspace, random, sin, cos
from scipy import interpolate

x = linspace(0, 10)

y = sin(x * .5) + cos (x * 2)  + random.randn(x.size) * 1e-1
# fit spline
spl = interpolate.InterpolatedUnivariateSpline(x, y)
fitx = linspace(0, x.max(), 100)

fig, ax = subplots()
ax.scatter(x, y)

ax.plot(fitx, spl(fitx))
fig.show()
cvanelteren
  • 1,633
  • 9
  • 16