2017-08-15 116 views
0

我試圖在滾動窗口中用matplotlib繪製快速數據(每秒1-10個數據點)。在滾動窗口中繪製快速傳入數據

我喜歡熊貓,因爲它很簡單。

我的問題是:

  1. 是我的框架,有效(關於使用熊貓,matplotlib的 「plt.draw」)?

  2. 如果循環運行了1'000'000'000次,那麼數據幀(self.df)會變得太大 - >在某個點刪除數據收集器,然後開始一個空的數據框?但那滾動窗口的連續性呢?

  3. 該示例在一段時間後開始變得非常緩慢。難道是因爲低效率的製圖由於低效利用的內存

  4. 控制檯或顯示一個警告:

MatplotlibDeprecationWarning: Using default event loop until function specific to this GUI is implemented warnings.warn(str, mplDeprecation)

我必須採取照顧?

在此先感謝

這是我到目前爲止有:

import numpy as np 
import matplotlib.pyplot as plt; plt.ion() 
import pandas as pd 
import matplotlib 
import matplotlib.gridspec as gridspec 
plt.style.use('ggplot') 
from pathlib import Path 
import datetime 
import matplotlib 


class tradeScreen(object): 

    def __init__(self): 
     self.rollingWindow = 100 
     self.df = pd.DataFrame(dict(time=np.NaN, bid=np.NaN, ask=np.NaN, limitBuy=np.NaN, limitSell=np.NaN, stopLoss=np.NaN), index=np.arange(self.rollingWindow)) 
     self.df['time'] = pd.to_datetime(self.df['time']) # format 'time' as datetime object 

     # initialise plot and line 
     plt.figure() 
     G = gridspec.GridSpec(2, 1) 

     self.axes_1 = plt.subplot(G[0, :]) 
     self.axes_1.set_ylabel('First Panel') 

     self.axes_2 = plt.subplot(G[1, :]) 
     self.axes_2.set_ylabel('Second Panel') 

     self.line1, = self.axes_1.plot(self.df['time'], self.df['bid']) 
     self.line2, = self.axes_1.plot(self.df['time'], self.df['ask']) 
     self.line3, = self.axes_1.plot(self.df['time'], self.df['limitBuy']) 
     self.line4, = self.axes_1.plot(self.df['time'], self.df['limitSell']) 
     self.line5, = self.axes_2.plot(self.df['time'], self.df['stopLoss']) 


    def plotter(self, tick, i): 

     df = self.df 
     rollingWindow = self.rollingWindow 

     current_time = pd.datetime.now() 

     df.loc[i, "bid"] = tick["bid"].values.item(0) 
     df.loc[i, "ask"] = tick["ask"].values.item(0) 
     df.loc[i, "limitBuy"] = tick["limitBuy"].values.item(0) 
     df.loc[i, "limitSell"] = tick["limitSell"].values.item(0) 
     df.loc[i, "stopLoss"] = tick["stopLoss"].values.item(0) 
     df.loc[i, "time"] = current_time 

     self.line1.set_data(pd.to_datetime(df['time'][:i].tail(rollingWindow)), df['bid'][:i].tail(rollingWindow)) 
     self.line2.set_data(pd.to_datetime(df['time'][:i].tail(rollingWindow)), df['ask'][:i].tail(rollingWindow)) 
     self.line3.set_data(pd.to_datetime(df['time'][:i].tail(rollingWindow)), df['limitBuy'][:i].tail(rollingWindow)) 
     self.line4.set_data(pd.to_datetime(df['time'][:i].tail(rollingWindow)), df['limitSell'][:i].tail(rollingWindow)) 
     self.line5.set_data(pd.to_datetime(df['time'][:i].tail(rollingWindow)), df['stopLoss'][:i].tail(rollingWindow)) 

     self.axes_1.autoscale_view(True, True, True) 
     self.axes_1.relim() 
     self.axes_2.autoscale_view(True, True, True) 
     self.axes_2.relim() 

     plt.draw() 
     plt.pause(0.00000000000000001) 


p = tradeScreen() 
i = 0 
for i in np.arange(300): 

    # generate random data point 
    t = pd.datetime.now() 
    bid = np.random.rand() 
    ask = np.random.rand() 
    limitBuy = np.random.rand() 
    limitSell = np.random.rand() 
    stopLoss = np.random.rand() 

    tick = pd.DataFrame(dict(time=t, bid=bid, ask=ask, limitBuy=limitBuy, limitSell=limitSell, stopLoss=stopLoss), 
         index=np.arange(1)) 

    p.plotter(tick, i) 
    i += 1 

回答

0

你可能想看看Animation模塊,使動畫在matplotlib。請參閱此鏈接解釋:http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/

對於後人,該網頁上的第一個例子,這給Animation系統的要點是:

""" 
Matplotlib Animation Example 

author: Jake Vanderplas 
email: [email protected] 
website: http://jakevdp.github.com 
license: BSD 
Please feel free to use and modify this, but keep the above information. Thanks! 
""" 

import numpy as np 
from matplotlib import pyplot as plt 
from matplotlib import animation 

# First set up the figure, the axis, and the plot element we want to animate 
fig = plt.figure() 
ax = plt.axes(xlim=(0, 2), ylim=(-2, 2)) 
line, = ax.plot([], [], lw=2) 

# initialization function: plot the background of each frame 
def init(): 
    line.set_data([], []) 
    return line, 

# animation function. This is called sequentially 
def animate(i): 
    x = np.linspace(0, 2, 1000) 
    y = np.sin(2 * np.pi * (x - 0.01 * i)) 
    line.set_data(x, y) 
    return line, 

# call the animator. blit=True means only re-draw the parts that have changed. 
anim = animation.FuncAnimation(fig, animate, init_func=init, 
           frames=200, interval=20, blit=True) 

使用(上最後一行blit=True)塊傳輸可能會改善表演。 但是,AFAIK matplotlib沒有考慮到性能而設計,而且您可以查看更適合此任務的其他庫,例如PyQtGraph

+0

嗨Diziet,非常感謝您的回覆。當我運行代碼時,它僅在_blit_clear a.figure.canvas.restore_region(bg_cache [a])中返回一些錯誤消息「C:\ Anaconda3 \ lib \ site-packages \ matplotlib \ animation.py」,第898行 KeyError: Traceback(last recent call last): _on_timer中的文件「C:\ Anaconda3 \ lib \ site-packages \ matplotlib \ backend_bases.py」,行1305 ... – Pat