I encountered the following situation:
My app is performing some calculations and displaying multiple plots at the same time. There are a couple of input widgets in the sidebar, which influence how the plots look like. So every time one of those input widgets is changed, the plots get rerendered.
Now, I would like to offer a button to download all of the plots currently shown as a zip file. Currently I implemented this using
st.download_button and passing the zipfile data as
data parameter (the zip file is created in memory using
It is working, however the problem is, that everytime an input widget changes and the plots change, the zipfile will be recreated which slows down the user experience - even though most of the time the user will not actually download the file.
I am rather looking for a solution to not only start the download by clicking a button, but also triggering the creation of the zip file only upon clicking the button.
def figs2zip(figs) -> bytes: # create zip file containing all figs in memory using io.BytesIO() .... # return zip file buffer return zip_buf # some input widgets ... # create multiple plots using matplotlib and display them for fig in figs: st.pyplot(fig) # => this is slow, because figs2zip() will run on EVERY script rerun and # always create a new zip file in memory st.download_button(label='Download plots', data = figs2zip(fig), filename='plots.zip', mime='application/zip')
I would much rather want a behavior like this:
if st.button('Download plots'): zip_buf = figs2zip(fig) trigger_download(zip_buf) # <--- How do you implement this? 🤨
I.e, the zip file gets only created when actually clicking the button, rather than on every script run. At the same time, after creating the file in memory the download dialogue should pop-up just like with