簡體   English   中英

在Matplotlib,Python中使用Animation函數進行緩慢的繪圖

[英]Slow ploting using Animation function in Matplotlib, Python

這些天來,我需要您的幫助來解決這個問題。 我可以繪制從手機藍牙傳輸並由筆記本電腦的COM端口接收的串行數據。 乍一看似乎還可以,但是最多可以每260 ms(〜3 fps)繪制一次。 但是,手機每100毫秒發送一次數據。 我很確定問題出在“ plot”和“ figure”命令,這使我感到困惑。 我感謝有人可以更正我的代碼:

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()

關於您的特殊情況,很難說什么,因為我們沒有您正在使用的串行連接部分。

但是,如果這只是其中包含某些點的線圖,則繪圖應比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()

我不想在這里踩任何腳趾,因為@ImportanceOfBeingErnest釘住了它,但是在他的示例中加點划線使我的幀率從50跳到了300。在他的示例中,這是這樣做的:我在進行更改的地方留下了評論

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 animateinit(): #tells our animator what artists will need re-drawing every time
    return line,text

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})
    return line,text #return the updated artists

#inform the animator what our init_func is and enable blitting
ani = animation.FuncAnimation(fig, animate, interval=0,init_func=animateinit, blit=True) 
plt.show()

mpl中的每個繪制調用都非常昂貴,因此,如果我們可以繪制的越少越好,那么將會看到巨大的加速。 通過告訴動畫師只重畫某些元素,我們避免了重畫軸標記,軸標簽,計算縮放比例等內容。這些東西看起來很簡單,但是它們很多,而且開銷很快就累加了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM