Plotting a animated stocks' prices using Matplotlib

Viewed 601

I am trying to animate a time-series plot with Matplotlib but the figure always comes out empty. I attached my code below. Any help would be appreciated

import yfinance as yf
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt

# loading the data
indices = ["^GSPC","TLT", ]
data = yf.download(indices,start='2020-01-01')
data = data['Adj Close']
inv_growth = (data.pct_change().dropna() + 1).cumprod()

# plotting the data

fig, ax = plt.subplots()

ax.set_xlim(inv_growth.index[0], inv_growth.index[-1])
ax.set_ylim(940, 1100)

line, = ax.plot(inv_growth.index[0], 1000)

x_data = []
y_data = []

def animation_frame(date):
    x_data.append(date)
    y_data.append(inv_growth.loc[date])
    
    line.set_xdata(x_data)
    line.set_ydata(y_data)
    
    return line,

animation = FuncAnimation(fig, 
                          func=animation_frame, 
                          frames=list(inv_growth.index), 
                          interval = 100)
plt.show()

1 Answers

Your problem is that you are trying to plot two values at the same time. If you want two lines, you have to create two lines and update their respective data. Here is a slightly simplified version of your code (also, your y-scale seemed to be a factor 1000 off).

import yfinance as yf
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt

# loading the data
indices = ["^GSPC","TLT", ]
data = yf.download(indices,start='2020-01-01')
data = data['Adj Close']
inv_growth = (data.pct_change().dropna() + 1).cumprod()

# plotting the data

fig, ax = plt.subplots()

ax.set_xlim(inv_growth.index[0], inv_growth.index[-1])
ax.set_ylim(0.940, 1.100)

line1, = ax.plot([], [])
line2, = ax.plot([], [])


def animation_frame(i):
    temp = inv_growth.iloc[:i]
    line1.set_data(temp.index, temp[0])
    line2.set_data(temp.index, temp[1])

    return line1,line2,

animation = FuncAnimation(fig, 
                          func=animation_frame, 
                          frames=range(inv_growth.index.size),
                          interval = 100)
plt.show()
Related