Python——使用Matplotlib和sympy solve()函数绘制椭圆曲线

5
我有一个椭圆曲线图。 我想沿着P,Q,R绘制一条直线(其中PQ将独立于此问题确定)。P的主要问题是sympy solve()返回另一个方程式,而它需要返回一个值,以便用于绘制P的x值。 换句话说,solve()应该返回一个值,所以我显然在这里做错了什么。 供参考,这是P + Q = R的样子:

enter image description here

我一直在查看文档和其他材料,但这是我自己陷入麻烦的程度:

from mpl_toolkits.axes_grid.axislines import SubplotZero
from pylab import *
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches
from matplotlib import rc
import random
from sympy.solvers import solve
from sympy import *


def plotGraph():
    fig = plt.figure(1)
    #ax = SubplotZero(fig, 111)
    #fig.add_subplot(ax)
    #for direction in ["xzero", "yzero"]:
        #ax.axis[direction].set_axisline_style("-|>")
        #ax.axis[direction].set_visible(True)
    #ax.axis([-10,10,-10,10])
    a = -2; b = 1
    y, x = np.ogrid[-10:10:100j, -10:10:100j]
    xlist = x.ravel(); ylist = y.ravel()
    elliptic_curve = pow(y, 2) - pow(x, 3) - x * a - b
    plt.contour(xlist, ylist, elliptic_curve, [0])
    #rand = random.uniform(-5,5)
    randmid = random.randint(30,70)
    #y = ylist[randmid]; x = xlist[randmid]
    xsym, ysym = symbols('x ylist[randmid]')
    x_result = solve(pow(ysym, 2) - pow(xsym, 3) - xsym * a - b, xsym) # 11/5/13 needs to return a value
    plt.plot([-1.5,5], [-1,8], color = "c", linewidth=1) # plot([x1,x2,x3,...],[y1,y2,y3,...])
    plt.plot([xlist[randmid],5], [ylist[randmid],8], color = "m", linewidth=1)
    #rc('text', usetex=True)
    text(-9,6,' size of xlist: %s \n size of ylist: %s \n x_coord: %s \n random_y: %s'
        %(len(xlist),len(ylist),x_result,ylist[randmid]),
        fontsize=10, color = 'blue',bbox=dict(facecolor='tan', alpha=0.5))
    plt.annotate('$P+Q=R$', xy=(2, 1), xytext=(3, 1.5),arrowprops=dict(facecolor='black', shrink=0.05))

##    verts = [(-5, -10),(5, 10)] # [(x,y)startpoint,(x,y)endpoint] #,(0, 0)]
##    codes = [Path.MOVETO,Path.LINETO] # related to verts[] #,Path.STOP]
##    path = Path(verts, codes)
##    patch = patches.PathPatch(path, facecolor='none', lw=2)
##    ax.add_patch(patch)

    plt.grid(True)
    plt.show()


def main():
    plotGraph()


if __name__ == '__main__':
    main()

最终,我想画一条线来显示P+Q=R,所以如果有人对如何编写代码以获取Q也有什么补充意见,将不胜感激。我正在自学Python和椭圆曲线,所以我相信任何入门级程序员都可以在2分钟内弄清楚我已经研究了一段时间的内容。

创建一个名为 ylist[randmid] 的符号并不会以任何方式将其与 Python 变量 ylistrandmid 相关联。 - asmeurer
你好。你有完整的解决方案吗? - user1088259
2个回答

9
我不知道你要计算什么,但这是一个可以绘制图形的代码:
import numpy as np
import pylab as pl

Y, X = np.mgrid[-10:10:100j, -10:10:100j]

def f(x):
    return x**3 -3*x + 5

px = -2.0
py = -np.sqrt(f(px))

qx = 0.5
qy = np.sqrt(f(qx))

k = (qy - py)/(qx - px)
b = -px*k + py 

poly = np.poly1d([-1, k**2, 2*k*b+3, b**2-5])

x = np.roots(poly)
y = np.sqrt(f(x))

pl.contour(X, Y, Y**2 - f(X), levels=[0])
pl.plot(x, y, "o")
pl.plot(x, -y, "o")

x = np.linspace(-5, 5)
pl.plot(x, k*x+b)

图表:

enter image description here


是的,谢谢,这很有帮助,也是我未来编码的好学习例子,+1并接受。 - stackuser
有没有办法也绘制坐标? - kelalaka
这个答案提供了一种使用 plot.figure 绘制坐标的方法;如何在Matplotlib中绘制图内的轴线? - kelalaka

0

根据HYRY的回答,我只是更新了一些细节以使其更好:

import numpy as np
import pylab as pl

Y, X = np.mgrid[-10:10:100j, -10:10:100j]

def f(x, a, b):
    return x**3 + a*x + b

a = -2
b = 4
# the 1st point: 0, -2
x1 = 0
y1 = -np.sqrt(f(x1, a, b))
print(x1, y1)

# the second point
x2 = 3 
y2 = np.sqrt(f(x2, a, b))
print(x2, y2)

# line: y=kl*x+bl
kl = (y2 - y1)/(x2 - x1)
bl = -x1*kl + y1 # bl = -x2*kl + y2

# y^2=x^3+ax+b , y=kl*x+bl => [-1, kl^2, 2*kl*bl, bl^2-b]
poly = np.poly1d([-1, kl**2, 2*kl*bl-a, bl**2-b])

# the roots of the poly
x = np.roots(poly)
y = np.sqrt(f(x, a, b))
print(x, y)

pl.contour(X, Y, Y**2 - f(X, a, b), levels=[0])
pl.plot(x, y, "o")
pl.plot(x, -y, "o")

x = np.linspace(-5, 5)
pl.plot(x, kl*x+bl)

我们得到了这个多项式的根:

[3. 2.44444444 0. ] [5. 3.7037037 2. ]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接