This class plots a curve. However, the inputs are currently set in main()
. I'd like to set them as user-driven from mouse interaction. Some of this is possible and in the Matplotlib docs (see referenced sites below) but it's still not really setting it up to be a 'click and plot'. So, ideally the user would click a button to set the P
and then whatever point (on the curve, has to be on the curve) they clicked next would be the new P
. Same with Q
. I'm sure this is a very simple question for anyone who's used Matplotlib but I'm teaching myself it right now, but it would probably take an entry-level dev just a few minutes to do something that I'm getting nowhere with.
Code:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid.axislines import SubplotZero
from math import sqrt
class ECC123(object):
def __init__(self,a,b,px,qx,qy):
self.a = a
self.b = b
self.pxlam = px
self.qxlam = qx
self.invertQy = qy
self.fig = plt.figure(1)
self.ax = SubplotZero(self.fig, 111)
def drawAxis(self):
#fig = plt.figure(1)
#ax = SubplotZero(fig, 111)
self.fig.add_subplot(self.ax)
for direction in ["xzero", "yzero"]:
self.ax.axis[direction].set_axisline_style("->")
self.ax.axis[direction].set_visible(True)
def plotGraph(self):
self.drawAxis()
y, x = np.ogrid[-10:10:100j, -10:10:100j] # range grid [from : to : how_many_points]
xlist = x.ravel(); ylist = y.ravel()
plt.contour(xlist, ylist, self.elliptic_curve(x,y), [0])
pylam = self.ecclambda(self.pxlam,self.a,self.b) # calculate P from pxlam
qylam = self.ecclambda(self.qxlam,self.a,self.b) # calculate Q from qxlam
if self.invertQy == 1: qylam = -qylam # optional, inverts qy to negative on the plot
plt.plot([self.pxlam,self.qxlam], [pylam,qylam], color = "c", linewidth=1)
plt.plot([self.pxlam], [pylam], "mo"); plt.plot([self.qxlam], [qylam], "mo")
plt.text(self.pxlam-0.25,pylam+0.5, '$P$'); plt.text(self.qxlam-0.25,self.qxlam+0.5, '$Q$')
s = (pylam - qylam)/(self.pxlam - self.qxlam) # calculate s slope
xr = s**2 - self.pxlam - self.qxlam # x-value of R
yr = pylam + s*(xr - self.pxlam) # y-value of -R; -y is R (inverted across x-axis)
plt.plot([xr],[yr],"mo")
plt.plot([xr],[-yr],"co")
plt.plot([self.qxlam,xr], [qylam,yr], color = "c", linewidth=1)
plt.plot([xr,xr], [yr,-yr], "x--")
plt.text(xr+0.25,yr, '$-R$'); plt.text(xr+0.25,-yr, '$R$')
plt.grid(True)
plt.show()
I've been going over the docs in Matplotlib, the scipy cookbook, and related questions here on SO and still not seeing exactly how to do this:
http://matplotlib.org/users/event_handling.html
http://matplotlib.org/1.3.1/api/widgets_api.html#matplotlib.widgets.Button.on_clicked
Cursors for data selection in matplotlib
How can I create a frontend for matplotlib?
http://wiki.scipy.org/Cookbook/Matplotlib
So far, I'm getting little red x's all over when I click and they don't even fall within the curve.