I have a dataframe in data_editor with a checkbox column. And I want to display the average age above the data_editor table in 2 metrics (checked rows and average age).
If I show the metrics below the data_editor, then the correct value is shown. The metrics above the data_editor are not refreshed (they are one click behind).
How can I refresh the metrics above the data_editor showing the correct metrics (the same values as the metrics below the data_editor)?
I ran into this issue with my app as well. The two solutions I went with were 1) Put the display after the check boxes, 2) rerun the page with a submit or update button. I know a lot of the community is requesting the ability to update certain portions of the page without reruning the entire script I would look into st.fragments and modal dialogs.
There may be other options but you can add an on_change argument to your data_editor. See the section Use Callbacks to update Session State. It would be something like
My go-to method is usually a callback as @S11 recommended. That will update the value before the script runs so it will be correct from the start of the page load.
Alternatively, a standard technique in Streamlit is to use containers to change the order of elements on the screen.
Create a container before your dataframe
After your dataframe, calculate your values.
Then, call st.metric and render it into the container above your data editor.
I don’t know your whole use-case, but just for reference, if you’re using the data editor just for row selections, version 1.35.0 of Streamlit does have this capability for st.dataframe and that would open up a third option: just get the selections directly from Session State from the dataframe’s key. This is also possible with st.data_editor, but is considerably more messy.
thanks for your reply, but
this is not working, still the same behavior when I add the callback function. Maybe this is not working because of the data editor.
code with the callback:
import streamlit as st
from streamlit import session_state as ss
import pandas as pd
def on_change_function():
ss.checked_rows = len(checked_rows)
if 'checked_rows' not in ss:
ss.checked_rows = 0
if 'average_age' not in ss:
ss.average_age = 0
#metrics above data_editor
st.metric(value=ss.checked_rows, label = "checked rows")
st.metric(value=ss.average_age, label = "average age checked rows")
# data sample
data = {
'Name': ['John', 'Anna', 'Peter', 'Linda'],
'Age': [28, 24, 35, 32],
'Year': [2034, 2023, 2023, 2014]
}
df = pd.DataFrame(data)
#insert checkbox column
df.insert(0, "check", False)
de = st.data_editor(df, key = 'data', on_change = on_change_function)
checked_rows= de[de['check']]
#checked rows
ss.checked_rows = len(checked_rows)
#average year
if len(checked_rows) != 0:
avg_age = checked_rows.agg(Age=('Age', 'average')).reset_index()
ss.average_age = avg_age['Age'][0]
#metrics below data_editor
st.metric(value=ss.checked_rows, label = "checked rows")
st.metric(value=ss.average_age, label = "average age checked rows")```
In the use case I have an update button, but it’s less user friendly that the user has to click a button (and it is hard to tell if the metrics are in sync with the detail data). So therefor I want to update the metric automatically. But if it is not working, I will go with your solution!
Since you are adding checked_rows to the SessionState before your metric (in the if statement), the initial value will be set to 0 (in the if statement). You can add an initial value = <> argument in st.metric if you want, but Streamlit will give you a warning that you are setting the value twice. After that, the st.session_state.checked_rows will continue to be updated as the value since that’s the key of the metric. Sorry I didn’t check your key names earlier, have now fixed my comment earlier.
MetricMixin.metric() got an unexpected keyword argument ‘key’
or
StreamlitAPIException: Values for st.button, st.download_button, st.file_uploader, st.data_editor, st.chat_input, and st.form cannot be set using st.session_state.
my code:
import streamlit as st
from streamlit import session_state as ss
import pandas as pd
def on_change_function()-> None:
ss.checked_rows = len(checked_rows)
if 'checked_rows' not in ss:
ss.checked_rows = 0
if 'average_age' not in ss:
ss.average_age = 0
#metrics above data_editor
# st.metric(value=ss.checked_rows, label = "checked rows")
# st.metric(key = ss.checked_rows, label = 'checked rows')
# st.metric(value=ss.average_age, label = "average age checked rows")
# data sample
data = {
'Name': ['John', 'Anna', 'Peter', 'Linda'],
'Age': [28, 24, 35, 32],
'Year': [2034, 2023, 2023, 2014]
}
df = pd.DataFrame(data)
#insert checkbox column
df.insert(0, "check", False)
# de = st.data_editor(df, key = 'data', on_change = on_change_function)
de = st.data_editor(df, key = 'checked_rows', on_change = on_change_function)
checked_rows= de[de['check']]
#checked rows
ss.checked_rows = len(checked_rows)
#average year
if len(checked_rows) != 0:
avg_age = checked_rows.agg(Age=('Age', 'average')).reset_index()
ss.average_age = avg_age['Age'][0]
#metrics below data_editor
# st.metric(value=ss.checked_rows, label = "checked rows")
# st.metric(value=ss.average_age, label = "average age checked rows")``````
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.