How can one "unshow" a dataframe?

Hi there!
I have an idea to implement to streamlit, but I can’t really understand how to do it.
So I have a dataframe which I showed using st.dataframe(). Now there is a button which the user can click, and some rows of the dataframe will be deleted (this is then saved into a new variable). This is implemented by having on_select=“multi-rows” in the original dataframe, and the user can choose the corresponding rows to delete.

Now the problem is, if the user wants to delete some rows from the table, I only want to show the resulting table (or, if possible, to hide the original table in an expander). In other words, I want to “unshow” the original table. Is there a way to do it? Using session_state does not help.

Here is a snippet of the code :

st.dataframe(
        df,
        key="df",
        on_select="rerun",
        selection_mode="multi-row",
    )

selected_rows = st.session_state["df"].selection["rows"]
if len(selected_rows):
        if st.button("Remove rows"):
            df_updated = df.drop(selected_rows)
            if len(df) != len(df_updated):
                st.dataframe(df_updated)

So here, I want to “unshow” the first dataframe. Is there a way to do it?
Thanks in advance

P.S. : Due to some reasons, I do not want to use st.data_editor() to delete the columns. I know that with st.data_editor, we can only show the current table, but this is not what I want.

I think session_state will work here, the order of operations are the problem

What’s happening in your code is the dataframe renders, then you make selections, then the code re-runs (before you hit any of the rest of the code). So you are just re-showing the original dataframe

if  ('df' in st.session_state and 'selection' in st.session_state["df"]
        and 'rows' in st.session_state["df"].selection):
    if st.button("Remove rows"):
        selected_rows = st.session_state["df"].selection["rows"]
        df = df.drop(selected_rows)

st.dataframe(
        df,
        key="df",
        on_select="rerun",
        selection_mode="multi-row",
    )

I haven’t used selections in st.dataframe before (just in data_editor), so apologies if the syntax is slightly off in the first if statement. But what this does is looks for whether any selections have been made already and, if so, check if the user has clicked the “Remove rows” button. Then, if so, drop any selected rows

Btw, it does not create a new df (df_updated) since keeping it as df allows the user to continue to select rows on the newly rendered dataframe

If you want the button under the dataframe, you will need to use a callback, so the df can update. If you click this dataframe, it will register which rows were selected, then rerun and then, if you hit the button, will remove those rows:

def set_remove_rows():
    if  ('df' in st.session_state and 'selection' in st.session_state["df"]
             and 'rows' in st.session_state["df"].selection):
        st.session_state.selected_rows = st.session_state["df"].selection["rows"]

def remove_rows():
    if 'selected_rows' in st.session_state:
        st.session_state.df = st.session_state.df.drop(st.session_state.selected_rows)

st.dataframe(
        df,
        key="df",
        on_select=set_remove_rows,
        selection_mode="multi-row",
    )

st.button("Remove rows", on_click=remove_rows)

If you’re willing to use a toggle instead of a button, you can also do something like this, which I think is slightly simpler and keeps the order of the df/toggle:

def remove_rows():
    if  ('df' in st.session_state and 'selection' in st.session_state["df"]
            and 'rows' in st.session_state["df"].selection
            and st.session_state.remove_rows):
        selected_rows = st.session_state["df"].selection["rows"]
        st.session_state.df = st.session_state.df.drop(selected_rows)

st.dataframe(
        df,
        key="df",
        on_select=remove_rows,
        selection_mode="multi-row",
    )

st.toggle("Remove rows", key="remove_rows")