我在使用Matplotlib动画(来自Arduino的串行端口数据)的Tkinter应用程序中获得不错的性能时遇到了一些问题,除了高性能桌面以外我认为我做的事情效率低下。
该应用程序按我想要的方式工作,一切正常显示,它只是相当滞后。基于测试,这似乎是matplotlib实现的一个问题,当动画运行时,一切都会慢下来。我曾试图在funcanimation中打开blitting,但这似乎没有什么区别。当它只是Tkinter没有图表时,它的时髦。
另一方面,当我只运行图表时(即没有用gui包裹),一切似乎都相对顺利。这可能是TkAgg的后端吗?或者是Tkinter与资源竞争,图形正在消耗更新线?
import matplotlib
import Tkinter as tk
import ttk
import tkFileDialog
import serial
import io
import os
import matplotlib.animation as animation
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib import style
from serialFunctions import findArduino #custom function to identify arduino from com port address
用于funcanimation的matplotlib代码:
fig = Figure()
ax = fig.add_subplot(111)
line, = ax.plot(np.random.rand(10), color = 'red', label = 'Velocity (cm/s)')
sio = io.TextIOWrapper(io.BufferedRWPair(arduino, arduino, 1))
#Data Update
tmin = 0.0
tmax = 10.0
def init():
line.set_data([], [])
return line,
def run(data):
t, y = data
#print t , y
xdata.append(t)
ydata.append(y)
line.set_data(xdata, ydata)
if t >= tmax- 1.00:
line.axes.set_xlim(t - tmax + 1.0, t + 1.0)
return line,
def data_gen():
'''Generator to pass data to the run function via funcanimation'''
t = 0
while True:
t+=0.1
try:
dat = float(sio.readline())
# print dat
except:
dat = 0
yield t, dat
ani = animation.FuncAnimation(fig, run, data_gen, init_func = init, interval=20, blit=False)
Tkinter相关代码:
matplotlib.use('TkAgg')
class StreamPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, {'bg': '#020b19'})
label = tk.Label(self, text = 'Begin Streaming', font = LARGE_FONT)
label.pack(pady = 10, padx = 10)
backButton = ttk.Button(self, text = 'Back',
command = lambda:
controller.show_frame(StartPage))
backButton.pack()
canvas = FigureCanvasTkAgg(fig, self)
canvas.show()
canvas.get_tk_widget().pack(side = tk.TOP, fill = tk.BOTH, expand = True)
#toolbar = NavigationToolbar2TkAgg(canvas, self)
#toolbar.update()
canvas._tkcanvas.pack(side = tk.TOP, fill = tk.BOTH, expand = True)
Arduino代码
int const potPin = A0;
int potVal;
void setup() {
// put your setup code here, to run once:
analogReference(DEFAULT); //EXTERNAL NO MORE THAN 5V!
Serial.begin(1200);
}
void loop() {
// put your main code here, to run repeatedly:
potVal = analogRead(potPin);
float voltage = potVal * (5.0/1024.0);
Serial.print(voltage);
Serial.print('\n');
}
答案 0 :(得分:0)
我在同样的性能问题上苦苦挣扎,并在这里找到了很好的建议: http://effbot.org/zone/tkinter-performance.htm
在run函数中调用update_idletasks对我来说大大提高了性能。