Я работаю над графическим интерфейсом tkinter со встроенными графами matplotlib.
На одном из вспомогательных участков я хочу, чтобы обновление графика было выполнено методом set_data, потому что мой друг Але доказал мне этобыло намного быстрее, чем повторять весь сюжет снова.
Я попытался вызвать set_data после создания объекта subplot с помощью self.curvas, а затем вызвать 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 ()
рабочий код, повторяющийся снова и снова график находится здесь: https://github.com/jrr1984/thorlabs_step_motors_ZST213B/blob/master/spectral_gui/main.py
скрипт, где я работаю, на тот случай, если вы хотите увидеть весь кусок кода, находится здесь: https://github.com/jrr1984/thorlabs_step_motors_ZST213B/blob/master/spectral_gui/jkdfha.py
графический интерфейс работает нормально, но я думаю, что метод set_data будет работать быстрее.
Спасибо заранее.