使用 matplotlib 在 Tkinter 中绘制数据 - 在列表之间切换
Plotting data in Tkinter with matplotlib - switching between lists
我正在创建一个利用 Tkinter
和 matplotlib
的程序。我有 2 个列表列表(一个用于 x 轴,一个用于 y 轴),我希望有一个按钮可以在列表中的列表之间切换。我从问题 Interactive plot based on Tkinter and matplotlib 中获取了很多代码,但我无法完全按照我喜欢的方式让按钮工作。我对使用 类 很陌生,理解它们有点困难。
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()
AttributeError: App instance has no attribute 'canvas'
表示您的代码在 created/assigned 之前引用了 canvas 属性。
这一行:
self.button_left = Button(frame,text="< Previous Event",
command=self.decrease(event_num))
正在调用 decrease
方法,因为您使用了括号并提供了参数,而不仅仅是绑定处理程序。在 decrease 方法中,您正在访问 self.canvas
以调用 draw 方法。
这是在您创建 canvas 属性之前发生的,它发生在这一行:
self.canvas = FigureCanvasTkAgg(fig,master=master)
使event_num
成为App
对象的属性;那么当你绑定它时你就不必将参数传递给处理程序。您可以通过在 __init__
.
中分配 self.event_num = 1
来做到这一点
我正在创建一个利用 Tkinter
和 matplotlib
的程序。我有 2 个列表列表(一个用于 x 轴,一个用于 y 轴),我希望有一个按钮可以在列表中的列表之间切换。我从问题 Interactive plot based on Tkinter and matplotlib 中获取了很多代码,但我无法完全按照我喜欢的方式让按钮工作。我对使用 类 很陌生,理解它们有点困难。
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()
AttributeError: App instance has no attribute 'canvas'
表示您的代码在 created/assigned 之前引用了 canvas 属性。
这一行:
self.button_left = Button(frame,text="< Previous Event",
command=self.decrease(event_num))
正在调用 decrease
方法,因为您使用了括号并提供了参数,而不仅仅是绑定处理程序。在 decrease 方法中,您正在访问 self.canvas
以调用 draw 方法。
这是在您创建 canvas 属性之前发生的,它发生在这一行:
self.canvas = FigureCanvasTkAgg(fig,master=master)
使event_num
成为App
对象的属性;那么当你绑定它时你就不必将参数传递给处理程序。您可以通过在 __init__
.
self.event_num = 1
来做到这一点