Facing issues when using two buttons in app which has independent functionalities?

Hi, I am new to streamlit and working on web visualizer app using 2 buttons functionalities locally, when first button is click displaying pandas data frame which is independent. While second button is click first button part is getting disappeared and app rerun again. But I want both buttons to work independently. I have added dataframe and button to session_state but still not working, So how can I do this?

This is my code:

with st.container():
    st.subheader(":rainbow[QUERY PLAYGROUND]", anchor=False)
    col1, col2 = st.columns([5, 1], gap="small", vertical_alignment="bottom")
    with col1:
        question = st.text_input(":orange[Input your question here:]", key="input", placeholder="Type here...")
    with col2:
        submit = st.button("Get Data", help="Click to submit your question.")

if "df" not in st.session_state:
    st.session_state.df = pd.DataFrame()

if "submit_btn" not in st.session_state:
    st.session_state["submit_btn"] = False

if "chart_btn" not in st.session_state:
    st.session_state["chart_btn"] = False

if submit:
    st.session_state["submit_btn"] = not st.session_state["submit_btn"]
    if question:
        sql_query = get_response(question, prompt)
        try:
            if sql_query:
                st.session_state.df = read_sql_query(sql_query, database_path)
                st.subheader(":grey[SQL Query:]", anchor=False) 
                st.code(sql_query, language='sql')
                if not st.session_state.df.empty:
                    st.subheader(":rainbow[Query Results:]", anchor=False)
                    st.dataframe(st.session_state.df)
                else:
                    st.write("""<h4 style="color: #ff3333;">No results found for the given query. Try another input...!</h4>""", unsafe_allow_html=True)
        except:
            st.error("Could not extract SQL query from the response. Please try again to retrieve data or change the input with respect to database.")
            st.stop()
    else:
        st.error("Please enter a valid Question related to database.")
        st.stop()


st.subheader(":rainbow[Chart Visualization:]", anchor=False)
col1, col2, col3 = st.columns(3)


with col1:
    chart_type = st.selectbox("Select Chart Type", ['Bar Chart', 'Line Chart', 'Pie Chart', 'Scatter Chart'])

with col2:
    x_col = st.selectbox("Select X-axis Column", st.session_state.df.columns)
    y_col = st.selectbox("Select Y-axis Column", st.session_state.df.columns)

with col3:
    generate = st.button("Generate")

if st.session_state["submit_btn"]:
    if generate:
        st.session_state["chart_btn"] = not st.session_state["chart_btn"]
        chart = generate_chart(st.session_state.df, chart_type, x_col, y_col)
        st.plotly_chart(chart)

Hello,
Here a example with two buttons :

import streamlit as st
import pandas as pd
import plotly.express as px
import numpy as np

# Create dummy data
def create_dummy_data():
    np.random.seed(0)
    dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
    data = {
        'Date': dates,
        'Sales': np.random.randint(100, 1000, size=len(dates)),
        'Customers': np.random.randint(10, 100, size=len(dates))
    }
    return pd.DataFrame(data)

# Initialize session state
if 'df' not in st.session_state:
    st.session_state.df = create_dummy_data()
if 'show_dataframe' not in st.session_state:
    st.session_state.show_dataframe = False
if 'show_plot' not in st.session_state:
    st.session_state.show_plot = False

# Button callbacks
def toggle_dataframe():
    st.session_state.show_dataframe = not st.session_state.show_dataframe

def toggle_plot():
    st.session_state.show_plot = not st.session_state.show_plot

# App layout
st.title("Dummy Data Visualization")

col1, col2 = st.columns(2)

with col1:
    st.button("Show/Hide Dataframe", on_click=toggle_dataframe)

with col2:
    st.button("Show/Hide Plot", on_click=toggle_plot)

# Display dataframe if button is clicked
if st.session_state.show_dataframe:
    st.subheader("Sales Data")
    st.dataframe(st.session_state.df)

# Display plot if button is clicked
if st.session_state.show_plot:
    st.subheader("Sales Over Time")
    fig = px.line(st.session_state.df, x='Date', y=['Sales', 'Customers'], 
                  title='Sales and Customers Over Time')
    st.plotly_chart(fig)

Some documentation : Button behavior and examples - Streamlit Docs

It look like you are not using the st.session_state correctly :
You can assign a widget with ‘key’
example:

st.button('example', key='this_is_example_widget')
# st.session_state['this_is_example_widget'] => value above

In my case, I don’t want to show/Hide the sections.
My flow is:

    • User type input and submit button is clicked then data is processed. Again if user tries to submit with different input then again new data will be processed.
    • Similarly with generate chart button also same scenario needs to implemented.
    • Both buttons should be independent as I am storing dataframe in session_state

You can use the same code as above to achieve the result you want. Here it’s on/off.
There is plenty of way to do the same thing :slight_smile:
You can use the st.session_state, on_click, key …


        col1, col2 = st.columns(2)
        def process_df():
            # Process the dataframe here
            st.session_state.df = st.session_state.df.sample(frac=1).reset_index(
                drop=True)  # Example: shuffle the dataframe
            st.session_state.show_dataframe = True
        with col1:
            if st.button("Process and Show Dataframe"):
                process_df()

        with col2:
            st.button("Show/Hide Plot", on_click=toggle_plot)

        # Display dataframe if button is clicked
        if st.session_state.show_dataframe:
            st.subheader("Sales Data")
            st.dataframe(st.session_state.df)

Here a example it will pre process each time you press the button.
And display the dataframe.