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()