Matplotlib Animation.FuncAnimation Support

Is there a way to display a matplotlib animation using the animation.FuncAnimation tool already developed in matplotlib.

For example, if I generate the animation:

ani = animation.FuncAnimation(fig, animate, interval=5000)

how to I show the output? Because streamlit.pyplot() does not show the real-time animation.

Please, any advice would be appreciated, I have tried every post related to animations and it does not work.

Hello @Zane_Venter,

I’ve discovered this little trick totally randomly, you can build HTML/JS out of a FuncAnimation and render it in Streamlit. Find it below :wink:

Hope it helps!
Fanilo

2 Likes

Hi,

I have tested the example (I think I did see it in a blog post), Streamlit loads the graph, but nothing gets displayed.

And then the following error gets displayed, due to the exit function (Its supposed to happen):

My Code example:

import mplfinance as mpf

import matplotlib.animation as animation

…A bunch of functions that get a pandas dataframe…

df = data

pkwargs=dict(type=‘candle’, tz_localize=False)

plt.style.use(‘fivethirtyeight’)

fig, axes = mpf.plot(data.iloc[0:20],returnfig=True,volume=False,
figsize=(11,8),
title=’\n\nLive Data’,
**pkwargs)

ax_main = axes[0]

ax_emav = ax_main

def animate(ival):
if (20+ival) > len(df):
print(‘no more data to plot’)
ani.event_source.interval *= 3
if ani.event_source.interval > 600000:
exit()
return
data = df.iloc[ival:(20 + ival)]
data_c = data.copy()
df_reg = reg_calc(data_c, ival)
ValB, ValS = function_to_calculate_extra_stuff(df_reg)
df_reg[‘ValA’] = Buy
df_reg[‘ValB’] = Sell
df_reg_c = df_reg

reg_plot = [
    mpf.make_addplot(df_reg_c['Hreg'], ax=ax_emav, type='line', color='g'),
    mpf.make_addplot(df_reg_c['Lreg'], ax=ax_emav, type='line', color='r'),
    mpf.make_addplot(df_reg_c['ValA'], ax=ax_emav, type='scatter',markersize=200,marker='^', color='b'),
    mpf.make_addplot(df_reg_c['ValB'], ax=ax_emav, type='scatter',markersize=200,marker='v',color='black'),
        ]
ax_main.clear()
ax_emav.clear()
mc = mpf.make_marketcolors(up='g', down='r')
s = mpf.make_mpf_style(marketcolors=mc)

mpf.plot(data, ax=ax_main, addplot=reg_plot, style=s, **pkwargs)

ani = animation.FuncAnimation(fig, animate, interval=1000)

st.markdown(“Simple animation examples — Matplotlib 2.1.2 documentation”)
components.html(ani.to_jshtml(), height=1000)

I hope that it makes sense. I really have been trying to get this to work on Streamlit.

Also, Its using live data, its not a fixed dataframe upload. Therefore the figure is plotted dynamically, this whole dynamic plot is getting to me…

Ah, unfortunately Matplotlib relies on generating static images at every Streamlit script rerun, so the FuncAnimation will also somewhere on the line be transformed to static animations, that doesn’t make it very friendly for live data. I usually go for Plotly, Altair or ECharts for dynamic plotting of data in the browser.
Then I would save the latest n points of live data in Streamlit cache and plot it on every tick.

GitHub - ash2shukla/streamlit-stream-stonks: An extended example of streaming application in streamlit of a Stocks Monitoring Dashboard. is my GOTO template for realtime plotting of windowed data in Streamlit and mostly uses this cycle. It uses asyncio (here a smaller example to reproduce locally) to pull data every n seconds, put it in a window cache and plot the results afterwards.

It’s a lot of information at once, but hope it does get you started on this solution!

Hi @Zane_Venter, I agree with @fanilo, but in case you want to follow in this direction, I’ve managed to show the animation, hope it is good for you:
(Edit: I had some lines missing, here is the corrected code :point_down: :sweat_smile:)

import streamlit as st
import streamlit.components.v1 as components

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
 

def func(t, line):
    t = np.arange(0,t,0.1)
    y = np.sin(t)
    line.set_data(t, y)
    return line
 
fig = plt.figure()
ax = plt.axes(xlim=(0, 100), ylim=(-1.2, 1.22))
redDots = plt.plot([], [], 'ro')
line = plt.plot([], [], lw=2)
 

# Creating the Animation object
line_ani = animation.FuncAnimation(fig, func, frames=np.arange(1,100,0.1), fargs=(line), interval=100, blit=False)
#line_ani.save(r'Animation.mp4')
 
 

#HtmlFile = line_ani.to_html5_video()
with open("myvideo.html","w") as f:
  print(line_ani.to_html5_video(), file=f)
  
HtmlFile = open("myvideo.html", "r")
#HtmlFile="myvideo.html"
source_code = HtmlFile.read() 
components.html(source_code, height = 900,width=900)
1 Like

Hi @andfanilo and @napoles3d ,

Thank you so much. This definitely helped me to get an better Idea of the solution, its still not 100% there but progress is progress and the guidance really helped me!

I have combined both recommendations, and its working with streamlit.

Thank you very much.

PS, I am getting this error, where I dont have permission to “add” the html file. When deploying the app.

mhhh, this is strange. I need to try to see what’s happening. Are you deploying in Streamlit Share?? Could you provide the link to the repo?