Search code examples
pythonstreamlit

Submit results to fill a dataframe in streamlit


I would like to build a streamlit app where the user gives some inputs and every time it uses the form_submit_button button, it will fill a dataframe row by row to collect user data. Currently I have the following app:

import streamlit as st
import pandas as pd
import numpy as np

# page

st.sidebar.header("Submit results")

with st.form('Form1'):
        option = st.selectbox(
                "Select the tracked you played:",
                ("ds Mario Kart", "Toad Harbour", "Koopa Cape"))
        number = st.slider("Pick a number", 1, 12)
        submitted1 = st.form_submit_button('Submit 1')

df = pd.DataFrame(np.array([[option, number]]), columns = ["Track", "Result"])
dfs = []
dfs.append(df)
df_combined = pd.concat(dfs)
st.dataframe(df_combined)

Output:

enter image description here

As you can see it creates the dropdown and slider. These return both a value. When we change the value and hit the submit button, the value does change in the dataframe. Unfortunately, the dataframe keeps being only one row. So I was wondering how we can fill the dataframe row by row every time we hit the submit button?


Solution

  • I adapted your code based on this documentation. Basically it uses session_state to remember data between threads and also a callback onAddRow associated with the submit button:

    import pandas as pd
    import streamlit as st
    
    st.sidebar.header("Submit results")
    
    if 'data' not in st.session_state:
        st.session_state["data"] = pd.DataFrame(columns=["Track", "Result"])
    
    def onAddRow():
        row = pd.DataFrame({'Track':[st.session_state["option"]], 'Result':[st.session_state["number"]]})
        st.session_state["data"] = pd.concat([st.session_state["data"], row])
    
    with st.form('Form1'):
        st.selectbox("Select track",  ("ds Mario Kart", "Toad Harbour", "Koopa Cape"), key="option")
        st.slider("Pick a number", 1, 12, key="number")
        st.form_submit_button('Submit 1', on_click=onAddRow )
    
    
    st.dataframe(st.session_state["data"])