这个问题可以用y作为x的函数来解决
关键在于,对于每个有效的x,有2个y值,在椭圆所跨越的x范围之外没有(或假想的)y解
下面是3.5代码,Sympy1.0应该很好,但打印,列表组件可能不能向后兼容到2.xfrom numpy import linalg
from numpy import linspace
import numpy as np
from numpy import meshgrid
import random
import matplotlib.pyplot as plt
from scipy import optimize
from sympy import *
xs = [1.02, 0.95, 0.87, 0.77, 0.67, 0.56, 0.44, 0.30, 0.16, 0.01]
ys = [0.39, 0.32, 0.27, 0.22, 0.18, 0.15, 0.13, 0.12, 0.12, 0.15]
b = [i ** 2 for i in xs] # That is the list that contains the results that are given as x^2 from the equation.
def fxn(x, y): # That is the function that solves the given equation to find each parameter.
my_list = [] #It is the main list.
for z in range(len(x)):
w = [0] * 5
w[0] = y[z] ** 2
w[1] = x[z] * y[z]
w[2] = x[z]
w[3] = y[z]
w[4] = 1
my_list.append(w)
return my_list
t = linalg.lstsq(fxn(xs, ys), b)
def ysolv(coeffs):
x,y,a,b,c,d,e = symbols('x y a b c d e')
ellipse = a*y**2 + b*x*y + c*x + d*y + e - x**2
y_sols = solve(ellipse, y)
print(*y_sols, sep='\n')
num_coefs = [(a, f) for a, f in (zip([a,b,c,d,e], coeffs))]
y_solsf0 = y_sols[0].subs(num_coefs)
y_solsf1 = y_sols[1].subs(num_coefs)
f0 = lambdify([x], y_solsf0)
f1 = lambdify([x], y_solsf1)
return f0, f1
f0, f1 = ysolv(t[0])
y0 = [f0(x) for x in xs]
y1 = [f1(x) for x in xs]
plt.scatter(xs, ys)
plt.scatter(xs, y0, s=100, color = 'red', marker='+')
plt.scatter(xs, y1, s=100, color = 'green', marker='+')
plt.show()
在Spyder中运行上述功能时:
^{pr2}$

为y值生成的函数并非处处有效:f0(0.1), f1(0.1)
Out[5]: (0.12952825130864626, 0.6411040771593166)
f0(2)
Traceback (most recent call last):
File "", line 1, in
f0(2)
File "", line 1, in
ValueError: math domain error
In [7]:
域错误需要try/execpt来“感知”有效的x范围或更多的数学运算
如以下尝试/例外:(编辑为“关闭”图纸重新注释)def feeloutXrange(f, midx, endx):
fxs = []
x = midx
while True:
try: f(x)
except:
break
fxs.append(x)
x += (endx - midx)/100
return fxs
midx = (min(xs) + max(xs))/2
xpos = feeloutXrange(f0, midx, max(xs))
xnegs = feeloutXrange(f0, midx, min(xs))
xs_ellipse = xnegs[::-1] + xpos[1:]
y0s = [f0(x) for x in xs_ellipse]
y1s = [f1(x) for x in xs_ellipse]
ys_ellipse = y0s + y1s[::-1] + [y0s[0]] # add y start point to end to close drawing
xs_ellipse = xs_ellipse + xs_ellipse[::-1] + [xs_ellipse[0]] # added x start point
plt.scatter(xs, ys)
plt.scatter(xs, y0, s=100, color = 'red', marker='+')
plt.scatter(xs, y1, s=100, color = 'green', marker='+')
plt.plot(xs_ellipse, ys_ellipse)
plt.show()
编辑:在椭圆终点列表中添加了重复的起点,以关闭打印地物ys_ellipse = y0s + y1s[::-1] + [y0s[0]] # add y start point to end to close drawing
xs_ellipse = xs_ellipse + xs_ellipse[::-1] + [xs_ellipse[0]] # added x start point