Autoplay a matplotlib animation jsthml element in streamlit

I have a matplotlib animation, that i need to present on my streamlit page. I used this line of code to build this.

components.html(anim.to_jshtml(fps=40, default_mode='once'), height=1000)

As a result, i get some kind of html player, where i can click on Play button and start my animation drawing, however i want that animation starts immediately when player appears. In other words, can i somehow set autoplay mode to the player?

Hey @egoxxx did you find a solution for this problem? Im also struggling with this.

Maybe there is a simpler solution, but you could add a javascript line to anim.to_jshtml() that automates the click on the play button.

document.querySelector('.anim-buttons button[title="Play"]').click();

Here is an example reusing the animation from this other forum post:

matplotlibanimate_autoplay

Code:
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
import streamlit as st
from itertools import cycle

## Generate some data
randomdata = np.random.random(size=(5,3,3))
harvest_cycle = cycle([i for i in randomdata])
harvest = next(harvest_cycle)

## Initialize figure
fig,ax = plt.subplots(figsize=[3,3])
ax.set_aspect('equal')
ax.grid(which = 'minor',color='w', linestyle='-', linewidth=2)
heatmap = ax.imshow(harvest)

## Animate 
def update(frame_number):
    ## Clears the data passed to the axes
    ##  This is important so the final figure does not store
    ##  every single frame and slows everything down 
    ax.cla()

    ax.imshow(next(harvest_cycle))
    ax.set_title(f"Frame: {frame_number}",fontsize=24)

animation = FuncAnimation(fig,update,frames=10)

## Export jshmtl representation
animjs = animation.to_jshtml()

### Inject JS for autoplay
import re

## JS line to find the play button and click on it
click_on_play = """document.querySelector('.anim-buttons button[title="Play"]').click();"""

## Search for the creation of the animation within the jshtml file created by matplotlib
pattern = re.compile(r"(setTimeout.*?;)(.*?})", re.MULTILINE | re.DOTALL)

## Insert the JS line right below that
new_animjs = pattern.sub(rf"\1 \n {click_on_play} \2", animjs)

st.markdown("## :control_knobs: Using `jshtml` from matplotlib")
cols = st.columns(2)
with cols[0]:
    "### πŸ›‘ No modification"
    st.components.v1.html(animjs,height=600)

with cols[1]:
    "### ▢️ Autoplay"
    st.components.v1.html(new_animjs,height=600)

<\details>

Thank you very much! This will do the job for now :slight_smile:

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.