I am trying to build a streamlit app that produces a 3D numpy array (stored in a variable called predicted_map) having size 10 x 100 x 100 as a result of a calculation. I wanted to add a st.download_button that provides the user of the app, access to this calculated array.
Initially, I tried
st.download_button(label='Download model prediction', data=predicted_map, file_name='prediction')
This generates an error because a bytes object (and not a numpy array) is expected in data
I think I don’t want to do something like:
st.download_button(label='Download model prediction', data=predicted_map.tobytes(), file_name='prediction')
because then the user of the app would have to do the decoding process back to numpy array on their side. The ideal scenario would be that they are directly able to receive a numpy array.
Wrapping the 3D numpy array as an Image object using Image.fromarray also seems to not work for such 3D arrays.
How could I download such an array directly? Any suggestions would be very appreciated. Thank you!
Thank you for walking us through what you’ve tried and what you don’t want to do.
Here’s how you can save predicted_map, a 3D numpy arrray, as a .npy file with st.download_button. The trick is to create an in-memory buffer with io.BytesIO, write to it using np.save(), and use st.download_button() to download this in-memory buffer as as an .npy file:
import streamlit as st
import numpy as np
import io
@st.experimental_memo
def load_data():
return np.random.rand(10, 100, 100)
# Create a 3D numpy array
predicted_map = load_data()
# Create an in-memory buffer
with io.BytesIO() as buffer:
# Write array to buffer
np.save(buffer, predicted_map)
btn = st.download_button(
label="Download numpy array (.npy)",
data = buffer, # Download buffer
file_name = 'predicted_map.npy'
)
Your users will be “directly able to receive a numpy array”, which they can load using np.load(predicted_map.npy).
I am trying to do the same with an image which is stored as an array. I use the code you provided but when I download the image, it says that I “file format is not supported” and I cannot see the image. You can see my code below:
edges = cv2.Canny(array, l_threshold, h_threshold)
st.image(edges,caption='Edges', use_column_width=True)
# Create an in-memory buffer
with io.BytesIO() as buffer:
# Write array to buffer
np.save(buffer, edges)
btn = st.download_button(
label="Download Image",
data = buffer, # Download buffer
file_name = 'Image.npy'
)
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.