Я действительно борюсь с живым сюжетом, используя FuncAnimation и Tkinter. Я не уверен, какая информация необходима, чтобы воспроизвести проблему. Пожалуйста, прости меня, если чего-то не хватает. В урезанной версии он работает нормально:
from numpy.random import normal
from numpy import exp
def fn(x):
A=3e-8
B=6e3
Inoise = 1e-10
if x == 0:
I = Inoise
elif A*x**2*exp(-B/x) < Inoise:
I = Inoise
else:
I = A*x**2*exp(-B/x)
return normal(1,0.4,1)[0]*I
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,NavigationToolbar2Tk
from matplotlib.animation import FuncAnimation
from matplotlib.pyplot import Figure
from tkinter import Frame
from queue import Queue
class LivePlotWindow(Frame):
def __init__(self, master,xlabel='',ylabel='',logx=False,logy=False):
Frame.__init__(self, master)
self.pack(fill='both', expand=1)
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
self.canvas = FigureCanvasTkAgg(self.fig, master=self)
self.toolbar = NavigationToolbar2Tk(self.canvas, self)
self.toolbar.update()
self.canvas.get_tk_widget().pack()
self.xlabel = xlabel
self.ylabel = ylabel
self.logx = logx
self.logy = logy
self.q = Queue()
self._axini()
def _axini(self):
self.ax.cla()
self.ax.set_xlabel(self.xlabel)
self.ax.set_ylabel(self.ylabel)
if self.logx==True:
self.ax.set_xscale('log', nonposx='clip')
if self.logy==True:
self.ax.set_yscale('log', nonposy='clip')
self.fig.tight_layout()
def _update(self,i):
print(i)
[x,y] = self.q.get(block=True)
print([x,y])
self.ax.plot(x,y,'b.') # update the data
def run(self,ncalls):
self._axini()
print(ncalls)
self.ani = FuncAnimation(self.fig, self._update, range(ncalls-1), interval=100, repeat=False)
print(ncalls)
def addP(self,x,y):
self.q.put([x,y])
def stop(self):
self.ani.event_source.stop()
from tkinter import Tk
root = Tk()
root.title('Kennlinien-Messprogramm')
root.geometry('700x500')
plot = LivePlotWindow(root,'Voltage in V','Current in A',logy=True)
n=100
plot.run(n)
for i in range(n):
plot.addP(i*10,fn(i*10))
root.mainloop()
Но когда я интегрирую его в GUI с меню, он просто не вызывает функцию анимации. Кажется, когда я передаю свой объект Plot как вызов команды, он больше не работает? Если я вызываю функцию запуска напрямую, она теряет работу. Я понятия не имею, почему:
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,NavigationToolbar2Tk
from matplotlib.animation import FuncAnimation
from matplotlib.pyplot import Figure
from tkinter import Tk,Frame,Menu
from queue import Queue
class LivePlotWindow(Frame):
def __init__(self, master,xlabel='',ylabel='',logx=False,logy=False):
Frame.__init__(self, master)
self.pack(fill='both', expand=1)
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
self.canvas = FigureCanvasTkAgg(self.fig, master=self)
self.toolbar = NavigationToolbar2Tk(self.canvas, self)
self.toolbar.update()
self.canvas.get_tk_widget().pack()
self.xlabel = xlabel
self.ylabel = ylabel
self.logx = logx
self.logy = logy
self.q = Queue()
self._axini()
def _axini(self):
self.ax.cla()
self.ax.set_xlabel(self.xlabel)
self.ax.set_ylabel(self.ylabel)
if self.logx==True:
self.ax.set_xscale('log', nonposx='clip')
if self.logy==True:
self.ax.set_yscale('log', nonposy='clip')
self.fig.tight_layout()
def _update(self,i):
print(i)
[x,y] = self.q.get(block=True)
print([x,y])
self.ax.plot(x,y,'b.') # update the data
def run(self,ncalls):
self._axini()
print(ncalls)
self.ani = FuncAnimation(self.fig, self._update, range(ncalls-1), interval=100, repeat=False)
print(ncalls)
def addP(self,x,y):
self.q.put([x,y])
def stop(self):
self.ani.event_source.stop()
from tkinter import Tk
root = Tk()
root.title('Kennlinien-Messprogramm')
root.geometry('700x500')
plot = LivePlotWindow(root,'Voltage in V','Current in A',logy=True)
def start(menu,plot):
menu.entryconfig('\u25B6', state='disabled')
menu.entryconfig('\u25A0', state='normal')
n=100
plot.run(n)
for i in range(n):
plot.addP(i*10,fn(i*10))
def stop(menu,plot):
plot.stop
menu.entryconfig('\u25B6', state='normal')
menu.entryconfig('\u25A0', state='disabled')
menu = Menu(root)
root.config(menu=menu)
menu.add_command(label='\u25B6', command=lambda: start(menu,plot))
#menu.entryconfig(1, fg='green')
menu.add_command(label='\u25A0', command=lambda: stop(menu,plot))
menu.entryconfig('\u25A0', state='disabled')
#start(menu,plot)
root.mainloop()
Любая помощь будет принята с благодарностью! ;)