阅读并绘制实时实时自我更新csv文件

时间:2017-12-08 06:40:01

标签: python pandas plot real-time pyqtgraph

所以,我有一个更新自己的.csv文件。我想用它做一些事情,我不知道如何处理它,希望你能帮助我。 csv中的数据如下所示: 没有标题。我可以加入日期和时间,也可以在没有分隔符的同一列中。

07/12/2017,23:50,113.179,113.182,113.168,113.180,113.187,113.189,113.176,113.186,144
07/12/2017,23:51,113.180,113.190,113.180,113.187,113.186,113.196,113.186,113.193,175
07/12/2017,23:52,113.187,113.188,113.174,113.186,113.193,113.194,113.181,113.192,340
07/12/2017,23:53,113.186,113.192,113.175,113.181,113.192,113.199,113.182,113.188,282
07/12/2017,23:54,113.181,113.183,113.170,113.171,113.188,113.188,113.176,113.179,74
07/12/2017,23:55,113.171,113.181,113.170,113.179,113.179,113.188,113.176,113.186,329
07/12/2017,23:56,113.179,113.189,113.174,113.181,113.186,113.195,113.181,113.187,148
07/12/2017,23:57,113.181,113.181,113.169,113.169,113.187,113.187,113.175,113.175,55
07/12/2017,23:58,113.169,113.183,113.169,113.182,113.175,113.188,113.175,113.187,246
07/12/2017,23:59,113.182,113.210,113.175,113.203,113.187,113.215,113.181,113.209,378
08/12/2017,00:00,113.203,113.213,113.180,113.183,113.209,113.220,113.187,113.190,651
08/12/2017,00:01,113.183,113.190,113.164,113.167,113.190,113.196,113.171,113.174,333
08/12/2017,00:02,113.167,113.182,113.156,113.156,113.174,113.188,113.162,113.163,265
08/12/2017,00:03,113.156,113.165,113.151,113.163,113.163,113.172,113.158,113.170,222
08/12/2017,00:04,113.163,113.163,113.154,113.159,113.170,113.170,113.159,113.166,148
08/12/2017,00:05,113.159,113.163,113.153,113.154,113.166,113.168,113.159,113.162,162

对于初学者,我有兴趣只使用前两个(或3个,如果日期和时间是分开的)这个练习的列。例如:

07/12/2017,21:54,113.098
07/12/2017,21:55,113.096
07/12/2017,21:56,113.087
07/12/2017,21:57,113.075
07/12/2017,21:58,113.087
07/12/2017,21:59,113.079

每隔一秒左右添加新行以及更近的日期时间。 我可以做点像

df = pd.read_csv("C:\\Users\\xxx\\Desktop\\csvexport\\thefile.csv")
print(df[-1:])

查看数据框的最后一行(尾部)

现在,我看不到如何执行以下操作并感谢您的帮助:

  1. 更新数据框,以便我有最新的版本可用于计算何时出现新行(不使用睡眠计时器?)

  2. 能够在新数据到达时自动绘制新更新数据的数据(x轴上的日期时间,y上浮动)

  3. 我在生成.csv文件的程序的命令窗口中看到的输出是这样的,如果重要的话

    asset 08/12/2017 05:16:37 float:113.336 floattwo:113.328 digit:20
    asset 08/12/2017 05:16:40 float:113.334 floattwo:113.328 digit:21
    asset 08/12/2017 05:16:40 float:113.335 floattwo:113.323 digit:22
    asset 08/12/2017 05:16:41 float:113.331 floattwo:113.328 digit:23
    asset 08/12/2017 05:16:43 float:113.334 floattwo:113.327 digit:24
    asset 08/12/2017 05:16:47 float:113.332 floattwo:113.328 digit:25
    

    所以你可以看到更新不是一秒钟,它们可以有间隙,有时也会在同一秒内发生(05:16:40两次)

    因此,我想要发生的是实际上以相等的时间间隔(1分钟,或5分钟等)保持绘图,但是根据属于该分钟的.csv中的浮动值继续更改最近的点。 。当下一分钟的一行到达时,只有那时情节才会向右移动(但随着浮点数的变化而不断波动)...希望你能得到这个想法。我想用pyqtgraph作为情节。

    我设法编写了这么多......但这不是最好的例子,对不起。当然情节不应该是这样的。只是说明我想看到的内容。因此绿色条应该不断改变值,直到下一步添加到csv

    import pyqtgraph as pg
    from pyqtgraph import QtCore, QtGui
    import pandas as pd
    import datetime
    
    x = pd.read_csv("C:\\Users\\xxx\\Desktop\\csvexport\\thefile.csv")
    z = x[-1:]
    
    def getlastrow():
        for a in z.iterrows():
            d = ((int(((a[1][0]).split("/")[0]))))
            m = ((int(((a[1][0]).split("/")[1]))))
            y = ((int(((a[1][0]).split("/")[2]))))        
            hh = ((int(((a[1][1]).split(":")[0]))))
            mm = ((int(((a[1][1]).split(":")[1]))))
            #ss = ((int(((a[1][1]).split(":")[2]))))        
            thedate = datetime.date(y, m, d)
            thetime = datetime.time(hh, mm)
            p = (a[1][2])
            return ((thedate,thetime,p))
    
    # print(str(getlastrow()[0]).replace("-",""))
    # print(getlastrow()[1])
    # print(getlastrow()[2])
    
    class CandlestickItem(pg.GraphicsObject):
        def __init__(self):
            pg.GraphicsObject.__init__(self)
            self.flagHasData = False
    
        def set_data(self, data):
            self.data = data
            self.flagHasData = True
            self.generatePicture()
            self.informViewBoundsChanged()
    
        def generatePicture(self):
            self.picture = QtGui.QPicture()
            p = QtGui.QPainter(self.picture)
            p.setPen(pg.mkPen('w'))
            w = (self.data[1][0] - self.data[0][0]) / 2.
            for (t, open) in self.data:
                p.drawLine(QtCore.QPointF(t, open), QtCore.QPointF(t, open))
                p.setBrush(pg.mkBrush('r'))
                if open > 122.8:
                    p.setBrush(pg.mkBrush('g'))
                p.drawRect(QtCore.QRectF(t-w, open, w*2, open))
            p.end()
    
        def paint(self, p, *args):
            if self.flagHasData:
                p.drawPicture(0, 0, self.picture)
    
        def boundingRect(self):
            return QtCore.QRectF(self.picture.boundingRect())
    
    app = QtGui.QApplication([])
    
    data = [
        [(int(str(getlastrow()[0]).replace("-",""))), (getlastrow()[2])],
        [(int(str(getlastrow()[0]).replace("-","")))+1, (getlastrow()[2])+0.1],
        [(int(str(getlastrow()[0]).replace("-","")))+2, (getlastrow()[2])+0.2],
    ]
    item = CandlestickItem()
    item.set_data(data)
    plt = pg.plot()
    plt.addItem(item)
    plt.setWindowTitle('pyqtgraph example: customGraphicsItem')
    
    def update():
        global item, data
        new_bar = (int(str(getlastrow()[0]).replace("-","")))+3, ((getlastrow()[2])+10)
        data.append(new_bar)
        item.set_data(data)
        app.processEvents()
    
    timer = QtCore.QTimer()
    timer.timeout.connect(update)
    timer.start(100)
    
    if __name__ == '__main__':
        import sys
        if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
            QtGui.QApplication.instance().exec_()  
    

1 个答案:

答案 0 :(得分:0)

希望下面的代码对第(1)点有帮助。我意识到这是一个部分答案。我用Linux测试过。代码应与操作系统无关,但我没有对此进行测试。

代码使用监视程序库监视TEST_DIR中定义的目录。如果更改了TEST_FILE中定义的文件,则会从名为MyHandler的事件处理类向主函数发送消息。每次更改文件时,我都会检查一些丑陋的时间,触发多个事件。因此,对于在THRESHOLD时间内发生的事件,只会触发一次调度。我把它设置为0.01秒。

将代码添加到dispatcher_receiver函数以读取更新的文件。

import ntpath
# pip3 install pydispatcher --user
from pydispatch import dispatcher
import sys
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler


MYHANDLER_SENDER = 'myhandler_sender'
MYHANDLER_SIGNAL = 'myhandler_signal'
TEST_FILE = 'test_data.csv'
TEST_DIR = '/home/bill/data/documents/infolab2/progs/jupyter_notebooks/pyqtgraph/test_data/'
THRESHOLD_TIME = 0.01


class MyHandler(FileSystemEventHandler):
    ''' handle events from the file system '''
    def __init__(self):
        self.start_time = time.time()

    def on_modified(self, event):
        now_time = time.time()
        # filter out multiple modified events occuring for a single file operation
        if (now_time - self.start_time) < THRESHOLD_TIME:
            print('repeated event, not triggering')
            return
        changed_file = ntpath.basename(event.src_path)
        if changed_file == TEST_FILE:
            print('changed file: {}'.format(changed_file))
            print('event type: {}'.format(event.event_type))
            print('do something...')
            # print(event)
            message = '{} changed'.format(changed_file)
            dispatcher.send(message=message, signal=MYHANDLER_SIGNAL, sender=MYHANDLER_SENDER)
        self.start_time = now_time


def main():
    dispatcher.connect(dispatcher_receive, signal=MYHANDLER_SIGNAL, sender=MYHANDLER_SENDER)
    observer = Observer()
    observer.schedule(event_handler, path=TEST_DIR, recursive=False)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

def dispatcher_receive(message):
    print('received dispatch: {}'.format(message))
    # read in the altered file

if __name__ == "__main__":
    event_handler = MyHandler()
    main()