在滚动窗口中绘制快速传入的数据

时间:2017-08-15 21:24:53

标签: python pandas matplotlib plot time-series

我尝试在滚动窗口中使用matplotlib绘制快速数据(每秒1-10个数据点)。

我喜欢熊猫,因为它很简单。

我的问题是:

  1. 我的框架是否有效(关于使用pandas,matplotlib'" plt.draw")?

  2. 如果循环运行的时间为1' 000' 000&000;数据帧(self.df)会变得太大 - >是否最好在某个时刻删除数据收集器,然后从空数据框开始?但那么滚动窗口的连续性呢?

  3. 一段时间后,这个例子开始变得很慢。是因为效率低下还是由于内存使用效率低下而导致

  4. 控制台显示警告:

  5.   

    MatplotlibDeprecationWarning:使用默认事件循环直到函数   特定于此GUI实现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
    

1 个答案:

答案 0 :(得分:0)

您可能需要查看Animation模块,以便在matplotlib中制作动画。请参阅此链接以获取解释:http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/

对于后人,该页面上的第一个示例是Animation系统的要点:

"""
Matplotlib Animation Example

author: Jake Vanderplas
email: vanderplas@astro.washington.edu
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)

在最后一行使用blitting(blit=True)可能会提高你的表现。 但是,AFAIK matplotlib的设计并未考虑到性能,您可以查看更适合此任务的其他库,例如PyQtGraph