【问题标题】:Showing matplotlib plots from function in tkinter在 tkinter 中显示来自函数的 matplotlib 图
【发布时间】:2021-10-02 03:18:53
【问题描述】:

我有一个关于在 tkinkter 中显示 pyplots 的问题。我有一个函数plot_function,它返回 4 个 matplotlib.pyplot-plots。我希望能够在 tkinter GUI 中显示这些图,并在开始时显示一个图,并用两个“下一个”和“上一个”按钮显示其他三个。 plot_funtion 只运行一次。

目前我正在尝试执行以下操作(简化):

import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
class GUI:

def plot_function(self):
    ...
    # Generating plots #
    ...
    self.plots = [plt1, plt2, plt3, plt4]
    self.init_plots()

def init_plots(self):    # Showing the inital plot, plt1
    self.plot_ctr = 0
    fig = plt.Figure(figsize=(5,4), dpi = 80)
    plot1 = fig.add_subplot(111)
    plot1.show(self.plots[0])
    first_fig = FigureCanvasTkAgg(fig,self.frame1)
    first_fig.draw()
    first_fig.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH)
    self.master.update_idletasks()


def next_plot(self):

    if self.plot_ctr < 3:
        self.plot_ctr += 1
    else: 
        self.plot_ctr = 0
    self.first_fig.config(image = self.plots[self.plots_ctr])
    self.master.update_idletasks()

def prev_plot(self):
    
    if self.plot_ctr > 0:
        self.plot_ctr -= 1
    else: 
        self.plot_ctr = 3
    self.first_fig.config(image = self.plots[self.plots_ctr])
    self.master.update_idletasks()

def __init__(self, master):
    self.master = master
    self.frame1 = tk.Frame(self.master, relief = tk.RAISED, highlightbackground = "black", highlightthickness = 1)
    self.frame1.pack(side = tk.TOP, fill=tk.BOTH, expand=True)
    self.next_btn = tk.Button(self.frame1, text = "Next plot", width = 10,  command = self.next_plot)
    self.prev_btn = tk.Button(self.frame1, text = "Previous plot", width = 10,  command = self.prev_plot)
    self.prev_btn.pack(side = tk.LEFT, padx = 10, pady = 10)
    self.next_btn.pack(side = tk.LEFT, padx = 10, pady = 10)
     

root = tk.Tk()
my_gui = GUI(root)
root.mainloop()

我对如何正确使用 TkAgg 感到非常不确定,并且非常感谢任何关于如何让它发挥作用的提示。

【问题讨论】:

    标签: python matplotlib tkinter


    【解决方案1】:

    这是一个示例,展示了如何组织代码以旋转嵌入在 tkinter 窗口中的一系列 matplotlib 图形

    import matplotlib
    import tkinter as tk
    
    matplotlib.use('TkAgg')
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
    from matplotlib.figure import Figure
    
    
    class Data:
    
        def __init__(self):
            self.x = list(range(10))
            self.y0 = self.x[:]
            self.y1 = [5 for _ in range(10)]
            self.y2 = [-y for y in self.y0]
            self.d = [self.y0, self.y1, self.y2]
    
        def get_next_dataset(self):
            y = self.d.pop(0)
            self.d.append(y)
            return self.x, y
    
    
    class MPLGraph(Figure):
    
        def __init__(self, data):
            Figure.__init__(self, figsize=(5, 5), dpi=100)
            self.data = data
    
        def obtain_next_figure(self):
            self.plot = self.add_subplot(111)
            self.plot.plot(*self.data.get_next_dataset())
            return self
    
    
    class GraphPage(tk.Frame):
        def __init__(self, parent, graphs):
            tk.Frame.__init__(self, parent)
            self.title_label = tk.Label(self, text="Graph Page Example")
            self.title_label.pack()
            self.pack()
            self.next_graph_btn = tk.Button(self, text='next graph', command=self.obtain_next_figure)
            self.next_graph_btn.pack()
            self.graphs = graphs
    
            self.obtain_next_figure()
    
        def obtain_next_figure(self):
            try:  # protects against AttributeError the first time when self.figure_widget not yet exists yet
                self.figure_widget.destroy()
            except AttributeError:
                pass
            self.add_mpl_figure(self.graphs.obtain_next_figure())
    
        def add_mpl_figure(self, fig):
            self.mpl_canvas = FigureCanvasTkAgg(fig, self)
            self.figure_widget = self.mpl_canvas.get_tk_widget()
            self.figure_widget.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
    
    
    if __name__ == '__main__':
    
        root = tk.Tk()
        graph_page = GraphPage(root, MPLGraph(Data()))
    
        root.mainloop()
    

    【讨论】:

      猜你喜欢
      • 2015-10-11
      • 2018-03-02
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-05
      • 2021-06-26
      • 2020-06-19
      相关资源
      最近更新 更多