Tkinter GUI中Matplotlib图形之间的干扰

Tkinter GUI中Matplotlib图形之间的干扰,matplotlib,tkinter,tkinter-canvas,Matplotlib,Tkinter,Tkinter Canvas,我通过这篇文章学习了如何将matploblib图嵌入Tkinter GUI。它似乎工作得很好 然而,我在让多个matplotlib图同时正常工作时遇到了一个问题,让我在这里进一步解释一下。下面的代码生成两个按钮,每个按钮链接到一个带有两个新按钮(加载数据和打印数据)的新窗口。您可以生成一些虚拟的两列数据,例如data1.txt、data2.txt、data3.txt、data4.txt,用于打印。我观察到的是(1)如果单独调用该窗口,则加载和打印data1.txt、data2.txt、data3

我通过这篇文章学习了如何将matploblib图嵌入Tkinter GUI。它似乎工作得很好

然而,我在让多个matplotlib图同时正常工作时遇到了一个问题,让我在这里进一步解释一下。下面的代码生成两个按钮,每个按钮链接到一个带有两个新按钮(加载数据和打印数据)的新窗口。您可以生成一些虚拟的两列数据,例如data1.txt、data2.txt、data3.txt、data4.txt,用于打印。我观察到的是(1)如果单独调用该窗口,则加载和打印data1.txt、data2.txt、data3.txt、data4.txt不会有问题。但是,如果同时打开两个窗口,则只能在第二个窗口中自由正确地打印,而第一个窗口不打印任何内容。第一个窗口似乎被第二个窗口的存在所抑制

谁能帮我理解这里发生了什么。我的matplotlib版本是2.0.2。Tkinter版本为$Revision:81008$。Python版本2.7.15。谢谢大家!

from Tkinter import *
import Tkinter as tk
import ttk
import tkFileDialog
import numpy
##loading matplotlib modules
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.gridspec as gridspec


class Overall_Look:
    def __init__(self, master):
        self.master = master

        self.top_frame = ttk.Frame(self.master, padding = (10, 10))
        self.top_frame.pack()

        ##here are the layout for step 1, load structure files

        ttk.Button(self.top_frame, text = "Button_1", command = self.plot_one,
                   style = "TButton").grid(row = 1, column = 0, columnspan = 2, padx = 5, sticky = "sw")
        ttk.Button(self.top_frame, text = "Button_2",command = self.plot_two,
                   style = "TButton").grid(row = 1, column = 2, columnspan = 2, padx = 5, sticky = "sw")

    def plot_one(self):
        self.plot_one = tk.Toplevel(self.master)
        self.GUI = Plot_One(self.plot_one)

    def plot_two(self):
        self.plot_two = tk.Toplevel(self.master)
        self.GUI = Plot_Two(self.plot_two)


class Plot_One():
    def __init__(self, master):
        self.master = master

        self.top_frame = ttk.Frame(self.master, padding = (10, 10))
        self.top_frame.pack()

        ##here are the layout for step 1, load structure files

        ttk.Button(self.top_frame, text = "Load Data 1", command = self.load_data_1,
                             style = "TButton").grid(row = 1, column = 0, columnspan = 2, padx = 5, sticky = "sw")
        ttk.Button(self.top_frame, text = "Plot Data 1",command = self.start_plot_one,
                             style = "TButton").grid(row = 1, column = 2, columnspan = 2, padx = 5)

        self.bottom_frame = ttk.Frame(self.master, padding = (10, 10))
        self.bottom_frame.pack()

        self.fig_1 = plt.figure(figsize=(5, 5), dpi=100) ##create a figure; modify the size here
        self.fig_1.add_subplot(111)

        self.fig_1.tight_layout()

        self.canvas = FigureCanvasTkAgg(self.fig_1, master = self.bottom_frame)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.bottom_frame)
        self.toolbar.update()
        self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)


    def load_data_1(self):
        self.data_1 = tkFileDialog.askopenfilename(defaultextension = ".txt",
                                                             filetypes = [("Text Documents", "*.txt")])

    def start_plot_one(self):

        data = numpy.loadtxt(self.data_1).transpose()
        x = data[0]
        y = data[1]

        self.fig_1.clf()
        self.fig_1.add_subplot(111)
        plt.plot(x, y, 'b-', lw=2)
        self.fig_1.tight_layout()
        self.canvas.draw()

class Plot_Two():
    def __init__(self, master):
        self.master = master

        self.top_frame = ttk.Frame(self.master, padding = (10, 10))
        self.top_frame.pack()

        ##here are the layout for step 1, load structure files

        ttk.Button(self.top_frame, text = "Load Data 2", command = self.load_data_2,
                   style = "TButton").grid(row = 1, column = 0, columnspan = 2, padx = 5, sticky = "sw")
        ttk.Button(self.top_frame, text = "Plot Data 2",command = self.start_plot_two,
                  style = "TButton").grid(row = 1, column = 2, columnspan = 2, padx = 5)

        self.bottom_frame = ttk.Frame(self.master, padding = (10, 10))
        self.bottom_frame.pack()

        self.fig_2 = plt.figure(figsize=(5, 5), dpi=100) ##create a figure; modify the size here
        self.fig_2.add_subplot(111)

        self.fig_2.tight_layout()

        self.canvas = FigureCanvasTkAgg(self.fig_2, master = self.bottom_frame)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.bottom_frame)
        self.toolbar.update()
        self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)


    def load_data_2(self):
        self.data_2 = tkFileDialog.askopenfilename(defaultextension = ".txt",
        filetypes = [("Text Documents", "*.txt")])

    def start_plot_two(self):

        data = numpy.loadtxt(self.data_2).transpose()
        x = data[0]
        y = data[1]

        self.fig_2.clf()
        self.fig_2.add_subplot(111)
        plt.plot(x, y, 'b-', lw=2)
        self.fig_2.tight_layout()
        self.canvas.draw()

def main():
    root = Tk()
    GUI = Overall_Look(root)
    root.mainloop()

if __name__ == "__main__": main()

在不详细阅读代码的情况下,我可以告诉您,在这种情况下,您根本不应该使用
pyplot
。删除pyplot导入,并用所处理对象的相应方法替换所有出现的pyplot导入。准确地说!如果我改用面向对象的绘图方式,即使用self.ax.plot(x,y),问题就解决了!谢谢你的专家回答!