Streamlit is a great tool, but I find it misses some very important features. One of them is the possibility to export a page as HTML. This would allow to have a copy of all plots, and all the text needed to generate reports and PDFs.
A further possibility would have been given adding an id
or at least a class
to streamlit plots, such as st.line_chart, in order to manage it in pure javascript behind the curtains. But alas the are not available.
To overcome this issue, I need to save plot as .PNG image, with the preference for echarts ones (for Sankey they are a lot better than Plotly’s ones).
Even if my problem is a multifaceted one, even answering to just one of my questions would provide me a big help.
For the curious:
- I am using echarts because in some cases (i.e. Sankey plot) they are well made.
- I use
streamlit_raw_echarts
instead ofstreamlit_echarts
because it provides the possibility to get the plot data using echarts’getDataURL()
.
Here is a minimal working code:
import streamlit as st
from streamlit_raw_echarts import st_echarts as st_echarts_raw
import base64
st.subheader("Start")
placeholder = st.empty()
with placeholder.container():
st.write("Create plot...")
option = {
"xAxis": {
"data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
},
"yAxis": {},
"series": [
{
"type": "bar",
"data": [23, 24, 18, 25, 27, 28, 25]
},
{
"type": "bar",
"data": [26, 24, 18, 22, 23, 20, 27]
}
]
}
img = st_echarts_raw(option, returnData={})
st.write("...plot created")
if img:
st.write(img[:60]+ "... and so on")
imgdata = base64.b64decode(img[22:])
with open("image.png", 'wb') as f:
f.write(imgdata)
st.success("and saved! :grinning:")
else:
st.error("Ops, no image to save :confused:")
# placeholder.empty() <==== removing the comment image is not saved
st.subheader("End")
Here are the questions
-
Is there any way to save an image programmatically after it has been created using plotly/bokeh/etc from streamlit, with or without other libraries? Not using a download link! I need to embed the image into a report, and cannot ask the user to save the images clicking on a button.
-
The plot must be visible in order to be saved. Removing the comment in
placeholder.empty()
the image is not saved at all. According to my logic, it should be saved and then removed from the placeholder BEFORE being visualized.
Is it possible to create an invisible plot in background? -
Sometimes the plot is incomplete when saved.
This is what is visualized:
and this is what is saved:
It happens with echarts Barcharts, while echarts Sankeys are ok (even if the style must be slightly manipulated because not all options, such as transparency, are used by streamlit_raw_echarts
)
Versions:
Streamlit 1.19
Python 3.8.2
Ubuntu 20.04
Tried with the latest versions of Firefox, Chrome, Brave Browsers.
Thanks in advance