2017-08-15 115 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