【问题标题】:realtime plotting pandas dataframe实时绘制熊猫数据框
【发布时间】:2017-10-10 01:57:09
【问题描述】:

我是 matplotlib 的新手,我试图显示我通过函数 read_API() 从 api 下载的三个变量的最后一小时数据的实时图。数据位于带有 DateTimeIndex 的 pandas 数据框中。 例如:

In: dframe.head()
Out:
                                 A          B         C
timestamp                                                            
2017-05-11 16:21:55        0.724931  0.361333   0.517720  
2017-05-11 16:22:25        0.725386  0.360833   0.518632
2017-05-11 16:22:55        0.725057  0.361333   0.521157
2017-05-11 16:23:25        0.724402  0.362133   0.520002

简化代码为:

import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
while True:
    dframe = read_API()
    dframe['timestamp'] = dframe['timestamp'] + pd.DateOffset(hours=timezone)
    dframe = dframe.set_index('timestamp')
    end = dframe.index.max()
    start= end.to_datetime() - dt.timedelta(hours=1)
    dframe = dframe.loc[start:end]
    plt.ion()
    fig, ax = plt.subplots()
    plt.pause(0.0001)
    ax.plot_date(dframe.index.to_pydatetime(), dframe,marker='', linestyle='solid')
    plt.draw()

它每隔几秒就会生成更新的图,但是: 1)每个情节出现在一个新窗口中(称为图1,图2,图3.....)。我想要一个带有情节覆盖前一个窗口的窗口 2)当每个情节出现时,它是空白的。然后出现另一个空白,然后出现另一个,然后第一个完成,依此类推。实际的绘图滞后了大约 3 个数字...... 我对情节和子情节的区别有点困惑,认为问题可能与此有关。

【问题讨论】:

    标签: python pandas animation matplotlib real-time-updates


    【解决方案1】:

    我认为您的代码的问题在于您每次刷新数据时都会调用fig, ax = plt.subplots()。这每次都会创建一个新的Figure,因此您会看到新的帧弹出。

    相反,您想在while 循环之外创建Figure,并且仅在加载新数据后刷新Axes

    我已使用您提供的基本示例创建了一个自我更新的Figure

    import pandas as pd
    import matplotlib.pyplot as plt 
    import datetime as dt
    
    data = [ 
        {'timestamp': '2017-05-11 16:21:55', 'A': 0.724931, 'B': 0.361333, 'C': 0.517720},
        {'timestamp': '2017-05-11 16:22:25', 'A': 0.725386, 'B': 0.360833, 'C': 0.518632},
        {'timestamp': '2017-05-11 16:22:55', 'A': 0.725057, 'B': 0.361333, 'C': 0.521157},
        {'timestamp': '2017-05-11 16:23:25', 'A': 0.724402, 'B': 0.362133, 'C': 0.520002},
    ]
    df = pd.DataFrame(data) 
    df.set_index("timestamp")
    
    plt.ion()
    fig, ax = plt.subplots()
    while True:
        dframe = df.copy()
        dframe['timestamp'] = pd.to_datetime(dframe['timestamp']) + pd.DateOffset(hours=2)
        dframe = dframe.set_index('timestamp')
        end = dframe.index.max()
        start= end.to_datetime() - dt.timedelta(hours=1)
        dframe = dframe.loc[start:end]
        plt.pause(0.0001)
        ax.plot_date(dframe.index.to_pydatetime(), dframe, marker='', linestyle='solid')
    

    编辑 1

    我无法重现引发的Warning,但我猜测它与pause 调用有关。也许尝试交换以下内容并编辑暂停时间。

       ax.plot_date(dframe.index.to_pydatetime(), dframe, marker='', linestyle='solid')
       plt.pause(0.01)
    

    编辑 2

    修复颜色非常简单。定义你的调色板,然后从中挑选。

    colors = ['r', 'g', 'b']
    
    plt.ion()
    fig, ax = plt.subplots()
    while True:
        dframe = df.copy()
        # Your data manipulation
        # ...
        dframe = dframe.loc[start:end]
        for i, column in enumerate(dframe.columns):
            ax.plot(dframe.index.to_pydatetime(), dframe[column], color=colors[i], marker=None, linestyle='solid')   
        plt.pause(0.1)
    

    如果您有更多列,请向colors 数组添加更多颜色。或者,根据dframe 中的列数即时生成它。

    【讨论】:

    • 你成功了。谢谢。不过,我收到了这个警告MatplotlibDeprecationWarning: Using default event loop until function specific to this GUI is implemented warnings.warn(str, mplDeprecation)
    • 请参阅我的回复中的编辑 1。此外,如果此答案对您的问题有所帮助,请接受它作为正确答案。
    • 谢谢,无论如何我都能接受警告。但是....知道如何让每条情节线保持自己的颜色吗?目前,线条会随着每次重新绘制而改变颜色。
    • 在我的回复中查看编辑 2
    猜你喜欢
    • 2016-01-07
    • 2020-01-14
    • 2017-05-28
    • 2017-06-09
    • 2015-02-04
    • 2018-02-10
    • 2022-01-08
    • 1970-01-01
    • 2019-12-14
    相关资源
    最近更新 更多