问题描述
我正在创建一个利用Tkinter
和matplotlib
的程序。
我有2个列表列表(一个用于x轴,一个用于y轴),我正在寻找一个可以在列表中的列表之间切换的按钮。
我从问题中提取了很多代码,但是我不能完全按我的该按钮。
我对使用类很陌生,在理解它们方面有些困难。
tft
是x数据tf1
是y数据
数据示例:
x-data = [[1,2,3,4,5],[10,11,13,15,12,19],[20,25,27]]
y-data = [[5.4,6,10,11,6],[4,6,8,34,20,12],[45,25,50]]
我下面的代码将显示列表中的列表之一,但是当我单击按钮时不会在列表中的列表之间切换。
我已经注释掉其他尝试过的方法。
它总是说我使用App时没有属性“ line
”或“ canvas
”。
就像我说的那样,我是班上的新手,我想更好地理解它们。
我已经更新了代码,现在它可以识别event_num
并在按下按钮时打印正确的值。
但是,该图不会使用新数据进行更新(即,它继续仅显示第一个数据集,而不是在列表之间切换)。
我相信问题在于函数的increase
和decrease
。我尝试使用self.line, = ax.plot(tft[self.event_num],tf1[self.event_num],'.')
和self.canvas.draw()
但无法正常运作。
我正在寻找要编辑的那部分,以便图形会改变。
class App:
def __init__(self, master):
self.event_num = 1
# Create a container
frame = Frame(master)
# Create 2 buttons
self.button_left = Button(frame,text="< Previous Event",
command=self.decrease)
self.button_left.grid(row=0,column=0)
self.button_right = Button(frame,text="Next Event >",
command=self.increase)
self.button_right.grid(row=0,column=1)
fig = Figure()
ax = fig.add_subplot(111)
fig.autofmt_xdate()
import matplotlib.dates as mdates
ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')
self.line, = ax.plot(tft[self.event_num],tf1[self.event_num],'.')
self.canvas = FigureCanvasTkAgg(fig,master=master)
self.canvas.show()
self.canvas.get_tk_widget().grid(row=1,column=0)
frame.grid(row=0,column=0)
def decrease(self):
self.event_num -= 1
print self.event_num
self.line, = ax.plot(tft[self.event_num],tf1[self.event_num],'.')
self.canvas.draw()
#self.canvas.draw(tft[self.event_num],tf1[self.event_num],'.')
#self.line.set_xdata(tft[event_num])
#self.line.set_ydata(tf1[event_num])
def increase(self):
self.event_num += 1
print self.event_num
self.line, = ax.plot(tft[self.event_num],tf1[self.event_num],'.')
self.canvas.draw()
#self.canvas.draw(tft[self.event_num],tf1[self.event_num],'.')
#self.set_xdata(tft[event_num])
#self.set_ydata(tf1[event_num])
root = Tk()
app = App(root)
root.mainloop()
1楼
AttributeError: App instance has no attribute 'canvas'
意味着您的代码在创建/分配canvas属性之前先引用了canvas属性。
这行:
self.button_left = Button(frame,text="< Previous Event",
command=self.decrease(event_num))
之所以调用decrease
方法,是因为您使用了括号并提供了参数,而不仅仅是绑定了处理程序。
在self.canvas
方法内部,您正在访问self.canvas
来调用draw方法。
这是在创建canvas属性之前发生的,该属性发生在此行上:
self.canvas = FigureCanvasTkAgg(fig,master=master)
将event_num
设为App
对象的属性;
则在绑定处理程序时,您不必将参数传递给该处理程序。
您可以通过在__init__
内分配self.event_num = 1
来实现。