在Matplotlib,Python中使用动画功能进行慢速绘图

时间:2016-11-22 16:40:02

标签: python matplotlib

我现在需要你帮助解决我正在处理它的问题。 我可以绘制一个从我的手机蓝牙传输并由我的笔记本电脑的COM端口接收的串行数据。乍一看似乎还不错,但最多可以每260毫秒(~3 fps)绘制一次。但手机每100毫秒发送一次数据。我很确定问题源于“情节”和“数字”命令让我感到困惑。如果有人能纠正我的代码我很感激:

from Tkinter import *
import serial
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)
ser = serial.Serial("COM4", baudrate=115200, timeout=0.1)
cnt=0
xComponent=[]
plt.ylim(0,30)
while (ser.inWaiting() == 0): # Wait here until there is data
    pass
def animate(i):

    BluetoothString = ser.readline()
    ser.flush()
    dataArray = BluetoothString.split(',')
    x = float(dataArray[2]) # we only need 3rd component
    xComponent.append(x)
    print xComponent
    ax1.clear()
    ax1.plot(xComponent)
    plt.ylim(0,25)
    global cnt
    if (cnt > 16): 
        xComponent.pop(0)
    else:
        cnt = cnt + 1

ani = animation.FuncAnimation(fig, animate, interval=0)
plt.show()

2 个答案:

答案 0 :(得分:1)

很难说出你的特殊情况,因为我们没有你正在使用的串行连接部分。

如果这只是一个带有一些点的线图,那么绘图应该比matplotlib中的3 fps快得多。 有一点你可以直接尝试不在每个迭代步骤中重新绘制所有内容,而是绘制一次,然后仅使用.set_data()

更新数据

以下示例与您的代码密切相关,并在我的计算机上以90 fps运行。所以也许你尝试一下,看看它是否有助于加快你的情况。

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time

fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)

cnt=0
xComponent=[]

line,  = ax1.plot([0], [0])
text = ax1.text(0.97,0.97, "", transform=ax1.transAxes, ha="right", va="top")

plt.ylim(0,25)
plt.xlim(0,100)
last_time = {0: time.time()}
def animate(i):

    if len(xComponent)>100:
        xComponent.pop(0)
    y = i % 25
    xComponent.append(y)

    line.set_data(range( len(xComponent) ) ,xComponent)
    new_time = time.time()
    text.set_text("{0:.2f} fps".format(1./(new_time-last_time[0])))
    last_time.update({0:new_time})


ani = animation.FuncAnimation(fig, animate, interval=0)
plt.show()

答案 1 :(得分:0)

我不想在这里踩任何脚趾,因为@ImportanceOfBeingErnest钉了它,但在他的例子中添加blitting会将我的帧率从50跳到300.这里是怎么做的在他的例子中这样做:我留下了我做出改变的评论

if @user && @user.authenticate(password)
  session[:user_id] = @user.id
  redirect_to root_path, notice: "Logged in successfully"
else 
  redirect_to login_path, alert: "Invalid Username/Password combination"
end

mpl中的每个绘图调用相当昂贵,所以如果我们尽可能少地绘制,我们会看到一个巨大的加速。通过告诉动画师只重新绘制某些元素,我们避免重新绘制诸如轴标记,轴标签,计算缩放等内容。这些事情看起来很简单,但是它们中有很多,并且开销很快就会增加。