0

I'm trying to resolve a task of realtime plotting from pandas DataFrame. The main task is to create a realtime graph from input timeframe based on realtime updating base. At first I tried to solve a task with only one real-time graph and completely done it. It works well with small and big timeframes. Next I have decided to make two graphs into one figure. So, I've done it, but it works really slower in small timeframes (etc 1 sec). If anybody have an ideas to resolve my problem I will be really appreciative.

I saw this topics and tried to combine the best answers but it didn't help me:

1) realtime plotting pandas dataframe

2) How to return an unknown number of objects in Python animation function

3) animated subplots using matplotlib

First code variant without FuncAnimation

import datetime

import matplotlib.pyplot as plt
import pandas as pd


def plots(exchange, pair, timeframe):
    points_amount = 24
    database = exchange + '_' + pair + '.csv'

    plt.ion()
    fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(12,5))
    plt.tight_layout()

    while True:
        df = pd.read_csv('{}'.format(database))
        our_df = df.copy()
        our_df['Date'] = pd.to_datetime(our_df['Date'])
        our_df.set_index('Date', inplace=True)  # try to delete inplace

        timeframe_df = our_df.resample('{}S'.format(timeframe)).agg(
            {'Price': lambda s: s.mean(),
             'Quantity': lambda s: s.mean()
             }
        )

        timeframe_df = timeframe_df[-200:]

        dframe = timeframe_df.copy()

        current_time = datetime.datetime.now()
        current_time = pd.to_datetime(current_time)
        delta_time = pd.Timedelta(seconds=timeframe * points_amount)
        past_time_limit = current_time - delta_time

        dframe = dframe.loc[timeframe_df.index > past_time_limit]

        #timelim = pd.Timedelta(seconds=timeframe * points_amount)
        #xlim_left = df.index.max() - timelim
        #ax[0].set_xlim(xlim_left, df.index.max())
        #ax[1].set_xlim(xlim_left, timeframe_df.index.max())

        ax[0].clear()
        ax[1].clear()
        #ax[0].figure.canvas.draw()
        #ax[1].figure.canvas.draw()

        ax[0].set_title('Price')
        ax[1].set_title('Quantity')

        ax[0].plot(dframe.index, dframe['Price'])
        ax[1].plot(dframe.index, dframe['Quantity'])

        plt.pause(timeframe)


An example of my code with FuncAnimation

def plots(exchange, pair, timeframe):
    """Create a real-time updated graph from database values"""

    # Number of points displayed on the chart
    points_amount = 24
    database = exchange + '_' + pair + '.csv'

    if not os.path.isfile(database):
        time.sleep(timeframe)
        plotter(exchange, pair, timeframe)


    fig, ax = plt.subplots(1, 2, figsize=(12, 5))

    def graphs_plotter(self):
        """Update graphs' parameters"""

        # Reading database and import it to pandas
        df = pd.read_csv('{}'.format(database))
        df['Date'] = pd.to_datetime(df['Date'])
        df.set_index('Date', inplace=True)

        # Creating a new timeframe according to input value
        timeframe_df = df.resample('{}S'.format(timeframe)).agg(
            {'Price': lambda s: s.mean(),
             'Quantity': lambda s: s.mean()
             }
        )

        timeframe_df = timeframe_df[-200:]

        current_time = datetime.datetime.now()
        current_time = pd.to_datetime(current_time)
        delta_time = pd.Timedelta(seconds=timeframe * points_amount)
        past_time_limit = current_time - delta_time

        timeframe_df = timeframe_df.loc[timeframe_df.index > past_time_limit]
        timelim = pd.Timedelta(seconds=timeframe * points_amount)
        xlim_left = df.index.max() - timelim

        ax[0].set_xlim(xlim_left, df.index.max())
        ax[1].set_xlim(xlim_left, timeframe_df.index.max())

        ax[0].plot(timeframe_df.index, timeframe_df['Price'])
        ax[1].plot(timeframe_df.index, timeframe_df['Quantity'])

        return ax

    ani = FuncAnimation(fig, graphs_plotter, interval=1000, repeat=False)

    plt.tight_layout()
    ax[0].grid()
    ax[1].grid()
    ax[0].figure.canvas.draw()
    ax[1].figure.canvas.draw()
    plt.show()
Evgeny
  • 1
  • 2

0 Answers0