簡體   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