【发布时间】:2013-11-29 18:58:19
【问题描述】:
这个类在 Matplotlib 中绘制曲线。用户鼠标输入部分将set_data() 更改为几个x,y 坐标。 P 和 Q 似乎正在正确重置。但是,当 R 未设置为使用相同方法(set_data() 或 set_x() 或 set_y())的计算时,则会导致错误:
TypeError: unsupported operand type(s) for ** or pow(): 'NoneType' and 'int'
当R 计算留在这会导致错误:
AttributeError: 'list' object has no attribute 'set_xdata'
整个类(它有点大,但方法是相互依赖的,我不想在这里遗漏一些可能相关的东西):
from mpl_toolkits.axes_grid.axislines import SubplotZero
import numpy as np
import matplotlib.pyplot as plt
from math import sqrt
class ECC(object):
def __init__(self,a,b,px,qx,qy):
"""
initialize input variables
"""
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)
self.xr = 0
self.yr = 0
def onclick(self, event):
x = event.xdata
if event.button == 1:
self.pxlam = x
if event.button == 3:
self.qxlam = x
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)
self.p = plt.plot([self.pxlam], [pylam], "mo")[0]
self.q = plt.plot([self.qxlam], [qylam], "mo")[0]
self.pt = plt.text(self.pxlam-0.25,pylam+0.5, '$P$')
self.qt = plt.text(self.qxlam-0.25,self.qxlam+0.5, '$Q$')
self.xr,self.yr = self.dataToPlotR(pylam,qylam)
plt.plot([self.xr],[self.yr],"mo")
plt.plot([self.xr],[-1*(self.yr)],"co")
self.rxdata = [self.qxlam,self.xr]; self.rydata = [qylam,self.yr]
self.r, = plt.plot(self.rxdata, self.rydata, color = "c", linewidth=1)
#plt.plot([xr,xr], [yr,-yr], "x--")
self.plotR(qylam)
plt.text(self.xr+0.25,self.yr, '$-R$'); plt.text(self.xr+0.25,-1*(self.yr), '$R$')
plt.text(-9,6,' P: (%s ,%s) \n Q: (%s ,%s) \n R: (%s ,%s) \n a: %s \n b: %s '
%(self.pxlam,pylam,self.qxlam,qylam,self.xr,-1*(self.yr),self.a,self.b),
fontsize=10, color = 'blue',bbox=dict(facecolor='tan', alpha=0.5))
self.update()
def update(self):
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
self.p.set_data([self.pxlam], [pylam])
self.q.set_data([self.qxlam], [qylam])
self.pt.set_x(self.pxlam-0.25)
self.pt.set_y(pylam+0.5)
self.qt.set_x(self.qxlam-0.25)
self.qt.set_y(qylam+0.5)
self.xr,self.yr = self.dataToPlotR(pylam,qylam)
#self.rxdata.set_xdata([self.qxlam,self.xr]) # R calculations
#self.rydata.set_ydata([qylam,self.yr]) # R calculations
plt.gcf().canvas.draw()
#self.plotR(self.xr,self.yr,qylam)
我上面提到的代码行,关于 R 方法是保留还是保留,在方法 update() 中注释掉了 2 行,然后用 # R calculation 注释掉。
我现在正在自学 Matplotlib,所以我确信初级程序员可以在很短的时间内看到我明显的错误,但我已经有一段时间了,而且进展不快。
我在这里要做的主要事情就是在每次点击后重新绘制线条和点,而不需要将任何先前设置的点保留在图表上。与图表左上角的文本框类似,每次单击后都应在此处重置值,而不是重写每个先前的文本字符串。
编辑:
我已经尝试过cla() 和clf(),但在这种情况下它们似乎不起作用。
事实上,在这个程序中,它们甚至可能在任何时候都不是必需的,因为我使用的 set_data() 方法应该足以根据每次点击的新数据重绘。为了证明这一点,只需在我的类中取消注释整个plotGraph() 方法并注释掉update() 中的相同代码,您会看到点P 和Q 将在单击后设置为新的。真正的问题是R 点、线条和左上角的文本框。
【问题讨论】:
-
另外,您应该发布完整的回溯,因为它们会告诉您问题出在哪一行。
-
@stackuser 我同意@tcaswell:您可以将代码示例限制在最低限度:
__init__和onClick足以描述问题仅限于更新的事实/删除一些对象。仅发布诸如“显示用户单击的框和行”之类的内容就会带来您需要处理的所有机制。此外,“路过”正是您对助手的期望,因此请接受批评。
标签: python math python-2.7 numpy matplotlib