Я строю графический интерфейс, используя tkinter, matplotlib и функцию анимации, которая должна отображать 3 разных субплота при нажатии кнопки графика. Эти графики должны быть обновлены в режиме реального времени без каких-либо замедлений, чтобы обеспечить бесперебойную работу приложения. Ось Y, которая является данными, полученными через TCP-соединение с эмулятором, а ось X должна быть временем обработки с момента нажатия кнопки.
Кроме того, мне удалось построить и отобразить данные, и в основном все работает, но через несколько секунд скорость построения графика, рисования линий и, я думаю, частота кадров падает, и она также становится чрезвычайно медленной. Мне не удалось найти способ начать смещение оси X графика влево, когда достаточно данных визуализируется.
Я попробовал новый подход после прочтения об этом и попытался использовать его, но мои графики не отображаются так, как будто мои данные отсутствуют там.
Так что я был бы очень признателен за помощь, если кто-то может помочь мне сделать визуализацию более быстрой и способной к смене, любая помощь, которая может указать мне правильный путь и показать мне, что я делаю неправильно, очень ценится ... Я я размещаю только те части кода, которые относятся к графику.
import tkinter
import tkinter.font
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backends._backend_tk import NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
style.use('ggplot')
## the lists am plotting st is system temp rp is rotor position and rs is rotor speed time is the x-axis and value is the y-axis
stime_st = []
svalue_st = []
stime_rp = []
svalue_rp = []
stime_rs = []
svalue_rs = []
## this class creates the canvas figure and toolbar
class ploting(tkinter.Frame):
def __init__(self, master):
tkinter.Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
global exit_bt
self.master.title("Plot Display")
self.pack(fill=tkinter.BOTH, expand=True)
self.canvas = FigureCanvasTkAgg(fig, master=self)
self.toolbar = NavigationToolbar2Tk(self.canvas,self)
self.toolbar.update()
close_bt = tkinter.Button(self,relief = 'raised', bg = '#668e99', font =myFont,text = 'Close', command = plot_close, width = 25)
close_bt.place(relx = 0.999,rely = 0.984, anchor = 'e')
exit_bt = tkinter.Button(self, font =myFont, bg = '#668e99',text = 'Exit Fullscreen', command = self.toggle, width = 25)
exit_bt.place(relx = 0.82,rely = 0.984, anchor = 'e')
self.canvas.get_tk_widget().pack(side= tkinter.BOTTOM, fill = tkinter.BOTH, expand = True) ## placing the canvas
self.canvas._tkcanvas.pack(side= tkinter.TOP, fill = tkinter.BOTH, expand = True)
self.master.attributes("-fullscreen", True)
def exit_fs(self):
self.master.attributes("-fullscreen", False)
def enter_fs(self):
self.master.attributes("-fullscreen", True)
def toggle(self):
if exit_bt.config('text')[-1] == 'Exit Fullscreen':
self.exit_fs()
exit_bt.config(text = 'Enter Fullscreen')
else:
self.enter_fs()
exit_bt.config(text = 'Exit Fullscreen')
## this function creates the figure, subplots, lines and main window as well as assigning limits and labels
def plot():
global plot_win
global fig
global rs
global rp
global st
global line_st
global line_rp
global line_rs
plt.ion()
fig = Figure(figsize = (5,5), dpi = 100)
rs = fig.add_subplot(311, position = [0.08,0.71,0.9,0.22])
rp = fig.add_subplot(312, position = [0.08,0.39,0.9,0.22])
st = fig.add_subplot(313, position = [0.08,0.07,0.9,0.22])
line_rs, = rs.plot(stime_rs,svalue_rs,'k-')
rs.set_xlabel("Time(s)")
rs.set_ylabel("Speed(RPM)")
rs.set_title("Rotor Speed")
line_rp, = rp.plot(stime_rp,svalue_rp,'k-')
rp.set_xlabel("Time(s)")
rp.set_ylabel("Position(DEG)")
rp.set_title("Rotor Position")
rp.set_ylim(0,360)
line_st, = st.plot(stime_st,svalue_st,'k-')
st.set_xlabel("Time(s)")
st.set_ylabel("Tempreture(C°)")
st.set_title("System Tempreture")
st.set_ylim(0,75)
plot_bt.config(state = 'disabled') ## this is irrelevant its from the main page of the GUI
newTime = time.process_time() ## time in seconds from the moment the plot is drawn
plot_win = tkinter.Tk()
plot_win.geometry("1280x800")
plot_win.protocol("WM_DELETE_WINDOW",plot_close)
app = ploting(plot_win) ## am creating the figure and canvas... etc
ani = animation.FuncAnimation(fig, animate, interval = 100, blit = True)
## ani is calling the animation function with blit to increase the speed and reduce unwanted drawings
app.mainloop()
## in this function if a connection to tcp is made that means i have data and in that case it will append the time and values into the list and set the ydata and xdata
def animate(i):
if conn_tcp.is_set():
stime_rs.append(newTime)
stime_rp.append(newTime)
stime_st.append(newTime)
svalue_rs.append(value_rs)
svalue_rp.append(value_rp)
svalue_st.append(value_st)
line_rs.set_ydata(svalue_rs)
line_rp.set_ydata(svalue_rp)
line_st.set_ydata(svalue_st)
line_rs.set_xdata(stime_rs)
line_rp.set_xdata(stime_rp)
line_st.set_xdata(stime_st)
return line_rs,line_rp,line_st,