I’ve recently found a bug in streamlit 1.46 with how overlayed altair charts are rendered when new data is supplied to their dataframes. when a feature that adds data to the table that the charts use is selected, the altair charts will disappear until you hover your mouse over the image. Especially annoying when its not me who will be using this app. I first noticed this issue in my app when updating from streamlit 1.41.1 to 1.44.1 and it’s persisted in the 1.46 update, so I’m hoping I can get an answer here as to why and if there’s a solution for my particular use case. Thanks!
To Reproduce:
import streamlit as st # 1.46
import pandas as pd
import altair as alt # 5.5
import numpy as np
x_input = st.selectbox("Select X-axis category:", ['A', 'B', 'C', 'D', 'E'])
y_input = st.selectbox("Select Y-axis category:", ['X', 'Y', 'Z', 'W', 'V'])
# Ensure scatter_data persists using session state
if 'scatter_data' not in st.session_state:
st.session_state.scatter_data = pd.DataFrame(columns=['category_x', 'category_y', 'point_value'])
scatter_data = st.session_state.scatter_data
# Temporary live-updating point
temp_point = pd.DataFrame({'category_x': [x_input], 'category_y': [y_input], 'point_value': ['Current']})
# Lock button functionality
if st.button('Lock'):
# Generate a new point value
new_value = len(scatter_data[(scatter_data['category_x'] == x_input) &
(scatter_data['category_y'] == y_input)]) + 1
# Add new row to scatter data
new_row = pd.DataFrame({'category_x': [x_input], 'category_y': [y_input], 'point_value': [new_value]})
st.session_state.scatter_data = pd.concat([scatter_data, new_row], ignore_index=True)
# Reset button functionality
if st.button('Reset'):
st.session_state.scatter_data = pd.DataFrame(columns=['category_x', 'category_y', 'point_value'])
# Create heatmap (static values for consistency)
heatmap_data = pd.DataFrame({
'category_x': ['A', 'B', 'C', 'D', 'E'] * 5,
'category_y': np.repeat(['X', 'Y', 'Z', 'W', 'V'], 5),
'heat_value': [5, 6, 7, 8, 9, 4, 3, 2, 1, 0, 5, 6, 7, 8, 9, 4, 3, 2, 1, 0, 5, 6, 7, 8, 9]
})
heatmap = alt.Chart(heatmap_data).mark_rect().encode(
x='category_x:O',
y='category_y:O',
color='heat_value:Q'
)
scatter = alt.Chart(scatter_data).mark_point(size=100).encode(
x='category_x:O',
y='category_y:O',
color=alt.value('red'),
tooltip=['point_value']
)
# Add temporary live-updating point
temp_scatter = alt.Chart(temp_point).mark_point(size=100, shape='circle').encode(
x='category_x:O',
y='category_y:O',
color=alt.value('blue'),
tooltip=['point_value']
)
# Add text labels below each dot
text_labels = alt.Chart(scatter_data).mark_text(dy=15).encode(
x='category_x:O',
y='category_y:O',
text='point_value:N',
color=alt.value('black')
)
# Combine heatmap, scatter plot, temporary point, and text labels
combined_chart = heatmap + scatter + temp_scatter + text_labels
# Display chart
st.altair_chart(combined_chart, use_container_width=True)