Python 我看不出我在实现set_数据时的错误,所以我不需要重新绘制整个绘图

Python 我看不出我在实现set_数据时的错误,所以我不需要重新绘制整个绘图,python,matplotlib,tkinter,Python,Matplotlib,Tkinter,我正在开发一个带有嵌入式matplotlib图形的tkinter GUI 在其中一个子地块上,我希望用set_data方法更新图形,因为我的朋友Ale向我证明,它比重新绘制整个地块快得多 在创建子图对象后,我尝试使用self.curvas调用set_数据,然后调用self.canvas.draw(),但它不会更新绘图 class SpectralPage(tk.Frame): # @profile def __init__(self,parent,controller): tk.Fram

我正在开发一个带有嵌入式matplotlib图形的tkinter GUI

在其中一个子地块上,我希望用set_data方法更新图形,因为我的朋友Ale向我证明,它比重新绘制整个地块快得多

在创建子图对象后,我尝试使用self.curvas调用set_数据,然后调用self.canvas.draw(),但它不会更新绘图

class SpectralPage(tk.Frame):
# @profile
def __init__(self,parent,controller):
    tk.Frame.__init__(self, parent)
    self.fig, (self.a0, self.a1) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [2.5, 1]})

    self.a0.imshow(img,interpolation='none', aspect='auto',origin= 'lower',extent=[0.0, 13000.0, 0, 24500.0])
    self.a0.set_ylabel('y [\u03bcm]')
    self.a0.set_xlabel('x [\u03bcm]')

    self.curva, = self.a1.plot([],[],'*') #referencia al artista
    self.a1.set_ylabel('Intensity [a.u.]')
    self.a1.set_xlabel('Wavelength [nm]')
    self.fig.tight_layout()
    self.canvas = FigureCanvasTkAgg(self.fig, self)
    self.canvas.draw()
    self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
    toolbar = NavigationToolbar2Tk(self.canvas, self)
    toolbar.update()
    self.canvas._tkcanvas.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)

    def init():
        self.curva.set_data([], [])
        return self.curva,
    self.ani = animation.FuncAnimation(self.fig,self.animate,init_func=init,interval=100)


@profile
def motion(self,event):
    x_move = event.xdata
    y_move = event.ydata
    if opt == 0 or opt == 1:

        if self.a0 == event.inaxes:
            x_lst = find_nearest(xy_pos_df.iloc[:,0],x_move)
            y_lst = find_nearest(xy_pos_df.iloc[:,1], y_move)
            mouse_pos = xy_pos_df[(xy_pos_df.iloc[:, 0] == x_lst) & (xy_pos_df.iloc[:, 1] == y_lst)].index.tolist()
            # self.a1.clear()
            # self.a1.set_ylabel('Intensity [a.u.]')
            # self.a1.set_xlabel('Wavelength [nm]')
            if len(mouse_pos) == 0:
                pass
            else:
                if normalization == True:
                    inten_norm = (inten_df.iloc[mouse_pos, :]/light_df.iloc[:]).abs()
                    if opt == 0:
                        self.curva.set_data(wavel_df.iloc[:, 0], inten_norm.transpose())
                        #self.a1.plot(wavel_df.iloc[:, 0], inten_norm.transpose(), '*')
                    if opt == 1:
                        clim = (350, 780)
                        norm = plt.Normalize(*clim)
                        wl = np.arange(clim[0], clim[1] + 1, 2)
                        colorlist = list(zip(norm(wl), [wavelength_to_rgb(w) for w in wl]))
                        spectralmap = matplotlib.colors.LinearSegmentedColormap.from_list("spectrum", colorlist)
                        mouse_pos = mouse_pos[0]
                        wavelengths = wavel_array #wavel_array[:, 0]
                        spectrum = np.transpose(inten_norm)
                        self.curva.set_data(wavel_array, spectrum)
                        # plt.plot(wavel_array, spectrum, color='darkred')

                        y = np.linspace(0, np.max(spectrum), 100)
                        X, Y = np.meshgrid(wavelengths, y)

                        extent = (np.min(wavelengths), np.max(wavelengths), np.min(y), np.max(y))

                        plt.imshow(X, clim=clim, extent=extent, cmap=spectralmap, aspect='auto')
                        plt.xlabel('Wavelength [nm]')
                        plt.ylabel('Intensity [a.u.]')

                        plt.fill_between(wavelengths, spectrum, np.max(spectrum), color='w')


                if normalization == False:
                    if opt == 0:
                        self.curva.set_data(wavel_df.iloc[:, 0], inten_df.iloc[mouse_pos, :].transpose())
                        return self.curva,
                        # self.a1.plot(wavel_df.iloc[:, 0], inten_df.iloc[mouse_pos, :].transpose(), '*')
                    if opt == 1:
                        clim = (350, 780)
                        norm = plt.Normalize(*clim)
                        wl = np.arange(clim[0], clim[1] + 1, 2)
                        colorlist = list(zip(norm(wl), [wavelength_to_rgb(w) for w in wl]))
                        spectralmap = matplotlib.colors.LinearSegmentedColormap.from_list("spectrum", colorlist)
                        mouse_pos = mouse_pos[0]
                        wavelengths = wavel_array  # wavel_array[:, 0]
                        spectrum = np.transpose(inten_df.iloc[mouse_pos, :])
                        # plt.plot(wavel_array, spectrum, color='darkred')
                        self.curva.set_data(wavel_array, spectrum)

                        y = np.linspace(0, np.max(spectrum), 100)
                        X, Y = np.meshgrid(wavelengths, y)

                        extent = (np.min(wavelengths), np.max(wavelengths), np.min(y), np.max(y))

                        plt.imshow(X, clim=clim, extent=extent, cmap=spectralmap, aspect='auto')
                        plt.xlabel('Wavelength [nm]')
                        plt.ylabel('Intensity [a.u.]')

                        plt.fill_between(wavelengths, spectrum, np.max(spectrum), color='w')


        else:
            # self.a1.clear()
            # self.a1.set_ylabel('Intensity [a.u.]')
            # self.a1.set_xlabel('Wavelength [nm]')
            return


def on_click(self, event):
    if self.a0 == event.inaxes:
        x_click = event.xdata
        y_click = event.ydata
        if opt == 2:
            # self.a1.clear()
            x_lst = find_nearest(xy_pos_df.iloc[:, 0], x_click)
            y_lst = find_nearest(xy_pos_df.iloc[:, 1], y_click)
            mouse_pos = xy_pos_df[(xy_pos_df.iloc[:, 0] == x_lst) & (xy_pos_df.iloc[:, 1] == y_lst)].index.tolist()
            if normalization == False:
                self.curva.set_data(wavel_df.iloc[:, 0], inten_df.iloc[mouse_pos, :].transpose())

                # self.a1.plot(wavel_df.iloc[:, 0], inten_df.iloc[mouse_pos, :].transpose(), '*')
            if normalization == True:
                inten_norm = (inten_df.iloc[mouse_pos, :] / light_df.iloc[:]).abs()
                self.curva.set_data(wavel_df.iloc[:, 0], inten_norm.transpose())
                # self.a1.plot(wavel_df.iloc[:, 0], inten_norm.transpose(), '*')



@profile
def animate(self,interval):
    if opt != 2:
        self.canvas.callbacks.connect('motion_notify_event',self.motion)
    if opt == 2:
        self.canvas.mpl_connect('button_press_event', self.on_click)
    self.canvas.draw()
app=SpectralGui() app.mainloop()

工作代码,一次又一次地重做绘图如下:

我工作的脚本(以防您想看到整个代码段)如下所示:

gui运行正常,但我认为使用set_data方法会运行得更快


Thx提前。

没有运行整个脚本,但非常确定更新后需要通过
self.canvas.draw\u idle()
重新绘制画布。感谢您的回答,Henry,在哪一行我应该包括self.canvas.draw\u idle()?Thx提前。我仍在调试代码。没有运行整个脚本,但非常确定更新后需要通过
self.canvas.draw\u idle()
重新绘制画布。感谢您的回答,Henry,在哪一行我应该包括self.canvas.draw\u idle()?Thx提前。我还在调试代码。