I have a dataframe called benchmark_returns
and strategy_returns
. Both have the same timespan. I want to find a way to plot the datapoints in a nice animation style so that it shows all the points loading in gradually. I am aware that there is a matplotlib.animation.FuncAnimation()
, however this typically is only used for a real-time updating of csv files etc but in my case I know all the data I want to use.
I have also tried using the crude plt.pause(0.01)
method, however this drastically slows down as the number of points get plotted.
Here is my code so far
x = benchmark_returns.index
y = benchmark_returns['Crypto 30']
y2 = benchmark_returns['Dow Jones 30']
y3 = benchmark_returns['NASDAQ']
y4 = benchmark_returns['S&P 500']
fig, ax = plt.subplots()
line, = ax.plot(x, y, color='k')
line2, = ax.plot(x, y2, color = 'b')
line3, = ax.plot(x, y3, color = 'r')
line4, = ax.plot(x, y4, color = 'g')
def update(num, x, y, y2, y3, y4, line):
line.set_data(x[:num], y[:num])
line2.set_data(x[:num], y2[:num])
line3.set_data(x[:num], y3[:num])
line4.set_data(x[:num], y4[:num])
return line, line2, line3, line4,
ani = animation.FuncAnimation(fig, update, fargs=[x, y, y2, y3, y4, line],
interval = 1, blit = True)
plt.show()
You can just update the data into the line element like so:
You could try
matplotlib.animation.ArtistAnimation
. It operates similar toFuncAnimation
in that you can specify the frame interval, looping behavior, etc, but all the plotting is done at once, before the animation step. Here is an exampleThe drawback here is that each artist is either drawn or not, i.e. you can't draw only part of a
Line2D
object without doing clipping. If this is not compatible with your use case then you can try usingFuncAnimation
withblit=True
and chunking the data to be plotted each time as well as usingset_data()
instead of clearing and redrawing on every iteration. An example of this using the same data from above:Edit
In response to the comments, here is the implementation of a chunking scheme using the updated code in the question:
or, more succinctly
and if you need it to stop updating after a certain time simply set the
frames
argument andrepeat=False
inFuncAnimation()
.