I have encountered an issue with the write_image
function in my Streamlit app when trying to save a Plotly figure as a PDF. The app is intended to display an electricity market plot, and I’ve used Plotly to create the plot and Streamlit to provide an option to download it as a PDF. However, when I click the “Download PDF” button, the downloaded PDF file is empty, and the plot is not displayed in the app.
Details:
- Running Environment: I am running the Streamlit app locally.
- Code: Here is a snippet of the relevant code from my app:
market_fig = go.Figure()
# ... (Plotly figure setup)
buffer = io.BytesIO()
market_fig.write_image(file=buffer, format="pdf")
st.download_button(
label="Download PDF",
data=buffer,
file_name="market_figure.pdf",
mime="application/pdf",
)
st.plotly_chart(market_fig, use_container_width=True)
- Troubleshooting Attempt: To further investigate the issue, I created a separate test script with a simplified Plotly figure and used the
write_image
function to save it as a PDF. The test script ran successfully and generated a PDF file with the plot, so it seems like the issue is specific to my Streamlit app.
Request for Assistance:
I am seeking help in identifying the root cause of this problem and finding a solution to ensure that the Plotly figure is correctly saved as a PDF and displayed in the Streamlit app. Any insights, suggestions, or guidance on how to resolve this issue would be greatly appreciated.
Additional Information:
- Full Error Message: I have not received any error messages, but the downloaded PDF is empty.
Thank you in advance for your assistance!
This is my full function that i want to transfer to pdf:
# Define the new function for the electricity market plot
def electricity_market():
st.title("Elektriciteit")
# Load the dataset from Parquet file
@st.cache_data
def load_data(file_path):
data = pd.read_parquet(file_path)
return data
parquet_file_path = r"C:\Users\.parquet"
data = load_data(parquet_file_path)
# Convert to datetime with explicit format
date_format = "%d-%m-%y %H:%M" # Adjust to match your data
data['Tijd (CET)'] = pd.to_datetime(data['Tijd (CET)'], format=date_format)
# Select relevant columns and drop NA values that might cause issues in the plot
market_data = data[['Tijd (CET)', 'PrijsDynamisch', 'Prijzen vast_variabel']].dropna()
# Resample the data to monthly frequency, using the mean for 'PrijsDynamisch'
monthly_data = market_data.resample('D', on='Tijd (CET)').mean() #now set on Day (D) can be set to whatever mean.
# Skip the months where the 'PrijsDynamisch' value is zero
monthly_data = monthly_data[monthly_data['PrijsDynamisch'] != 0]
# Check if the resampled data has any rows
if monthly_data.empty:
st.error("No data available for plotting after resampling and filtering.")
return
# Create a new figure for the market plot
market_fig = go.Figure()
market_fig.add_trace(go.Scatter(x=monthly_data.index, y=monthly_data['PrijsDynamisch'], mode='lines+markers', name='PrijsDynamisch',
marker=dict(size=1)))
market_fig.add_trace(go.Scatter(x=monthly_data.index, y=monthly_data['Prijzen vast_variabel'], mode='lines+markers', name='Prijzen vast_variabel',
marker=dict(size=1)))
# Update the layout to format the x-axis with months
market_fig.update_layout(
xaxis=dict(
tickformat='%b %Y', # abbreviated month name with year
type='date' # Ensures that the x-axis is treated as a date
),
title='Marktprijs versus vast/variable',
xaxis_title='Maand',
yaxis_title='Prijs (€)',
legend=dict(
orientation='h',
xanchor='center',
x=0.20,
y=-0.3 # Adjust this value as needed to position the legend below the plot
)
)
# Create an in-memory buffer
buffer = io.BytesIO()
# Save the figure as a PDF to the buffer
#market_fig.write_image(file=buffer, format="pdf")
# Download the PDF from the buffer
st.download_button(
label="Download PDF",
data=buffer,
file_name="market_figure.pdf",
mime="application/pdf",
)
# Display the Plotly chart
st.plotly_chart(market_fig, use_container_width=True)