繁体   English   中英

将matplotlib画布嵌入到tkinter GUI中-图未显示,但未引发任何错误

[英]Embedding matplotlib canvas into tkinter GUI - plot is not showing up, but no error is thrown

运行以下python python脚本不会显示嵌入式matplotlib图。 但是,它也不会引发任何错误消息。 运行脚本后,应该显示一个GUI,该GUI在左侧显示4个按钮,在右侧显示一个实时图形。 该图从文本文件'sample_graph_data.txt'接收其输入,该文件与脚本位于同一目录中。 脚本中有什么问题以及如何使它起作用?

#Script begins here
from tkinter import * 
from tkinter import messagebox
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib import animation
from matplotlib import style
from matplotlib.figure import Figure
PROGRAM_NAME = 'Smart Farm Controller'
style.use('ggplot')

fig = Figure(figsize=(5, 30), dpi=100)
a = fig.add_subplot(111)

class Controller:

    def __init__(self, root):
        self.root = root
        self.root.title(PROGRAM_NAME)
        self.root.protocol('WM_DELETE_WINDOW', self.exit_app)
        self.init_gui()

    def create_right_graphs(self):
        right_frame = Frame(self.root)
        right_frame.grid(row=2, column=6, sticky=N+E+W+S,
                         padx=2, pady=2)
        anim = animation.FuncAnimation(fig, self.animate_graph(right_frame),
                                       interval=1000)

    def create_left_switches(self):
        left_frame = Frame(self.root)
        left_frame.grid(row=2, column=1, columnspan=6, sticky=N+E+W+S,
                        padx=2, pady=2)
        led_button = Button(left_frame, text='LED') #command=self.on_led_button_clicked)
        led_button.config(height=2, width=30)
        led_button.grid(row=2, column=0, padx=4, pady=8)
        apump_button = Button(left_frame, text='Air Pump') #command=self.on_apump_button_clicked)
        apump_button.config(height=2, width=30)
        apump_button.grid(row=3, column=0, padx=4, pady=8)
        wpump_res_button = Button(left_frame, text='Reservoir Water Pump')
                                    #command=self.on_wpump_res_button_clicked)
        wpump_res_button.config(height=2, width=30)
        wpump_res_button.grid(row=4, column=0, padx=4, pady=8)
        wpump_grow_button = Button(left_frame, text='Grow Bucket Water Pump')
                                    #command=self.on_wpump_grow_button_clicked)
        wpump_grow_button.config(height=2, width=30)
        wpump_grow_button.grid(row=5, column=0, padx=4, pady=8)

    def animate_graph(self, right_frame):
        pullData = open("sample_graph_data.txt","r").read()
        dataList = pullData.split('\n')
        xList = []
        yList = []
        for eachLine in dataList:
            if len(eachLine)>1:
                x, y = eachLine.split(',')
                xList.append(int(x))
                yList.append(int(x))

        a.clear()
        a.plot(xList, yList)
        canvas = FigureCanvasTkAgg(fig, right_frame)
        canvas.show()
        canvas.get_tk_widget().pack(side=RIGHT, fill=BOTH, expand=True)

    def init_gui(self):
        self.create_right_graphs()
        self.create_left_switches()

    def exit_app(self):
        if messagebox.askokcancel("Quit", "Really quit?"):
            self.root.destroy()


if __name__ == '__main__':
    root = Tk()
    Controller(root)
    root.mainloop()

在运行时,问题的代码中确实没有触发任何错误,但是它也没有按预期运行。 根本不会触发某些错误,因为从未调用过代码的各个部分。
有几个问题:

  • 您实际上需要将FigureCanvas添加到动画外部的Frame
  • 始终保留要处理的对象的引用。 特别是动画必须保持活力。 最好通过使用self将其设为类属性来完成此操作。
  • 您实际上需要将框架放置在根窗口中。 这可以使用pack完成。
  • 在FuncAnimation内部,您不能调用该函数进行动画处理,而只能将其作为参数提供。 另外,您需要提供一些帧来制作动画,以使动画开始。 FuncAnimation(fig, self.animate_graph, frames=12)代替 FuncAnimation(fig, self.animate_graph(someargument))
  • 动画功能需要一个参数,该参数是帧编号(或frames参数给定的列表中的列表条目)。 如果需要,您可以提供其他参数(在这种情况下,请参考文档)。

我确定我也忘记提及其他一些事情。 但是,这是一个正在运行的代码。

from tkinter import * 
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib import animation
from matplotlib import style
from matplotlib.figure import Figure
style.use('ggplot')

fig = Figure(figsize=(5, 4), dpi=100)
a = fig.add_subplot(111)

class Controller:

    def __init__(self, root):
        self.root = root
        self.create_left_switches()
        self.create_right_graphs()    

    def create_right_graphs(self):
        right_frame = Frame(self.root)
        right_frame.grid(row=2, column=6, sticky=N+E+W+S,
                         padx=2, pady=2)
        right_frame.pack(fill=X, padx=5, pady=5)
        self.canvas = FigureCanvasTkAgg(fig,right_frame ) 
        self.canvas.get_tk_widget().pack(side=RIGHT, fill=BOTH, expand=True)

        self.anim = animation.FuncAnimation(fig, self.animate_graph, frames=12,
                                       interval=500, repeat=True)
        self.canvas.show()

    def create_left_switches(self):
        left_frame = Frame(self.root)
        left_frame.grid(row=2, column=1, columnspan=6, sticky=N+E+W+S,
                        padx=2, pady=2)
        left_frame.pack(fill=X, padx=5, pady=5)
        led_button = Button(left_frame, text='LED') #command=self.on_led_button_clicked)
        led_button.config(height=2, width=30)
        led_button.grid(row=2, column=0, padx=4, pady=8)


    def animate_graph(self, i):
        pullData = open("sample_graph_data.txt","r").read()
        dataList = pullData.split('\n')
        xList = []
        yList = []
        for eachLine in dataList:
            if len(eachLine)>1:
                x, y = eachLine.split(',')
                xList.append(int(x))
                yList.append(int(y)**(1+i/12.))

        a.clear()
        a.plot(xList, yList)

if __name__ == '__main__':
    root = Tk()
    Controller(root)
    root.mainloop()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM