Dataframe with selection column, possible to make single row selection?

Hello, i have a locally run app where i used this technique to create a dtaframe with row selections. My question is if it is possible to make the dataframe work in a way that only one row is selectable, e.g. if one selected more then one row then the previous row would get unselected.

Thank you very much for your help and greetings

@Plugs, I hope this is what you are looking.

import streamlit as st
import pandas as pd
from st_aggrid import AgGrid
from st_aggrid.grid_options_builder import GridOptionsBuilder


df = pd.DataFrame(
    {
        "Animal": ["Lion", "Elephant", "Giraffe", "Monkey", "Zebra"],
        "Habitat": ["Savanna", "Forest", "Savanna", "Forest", "Savanna"],
        "Lifespan (years)": [15, 60, 25, 20, 25],
        "Average weight (kg)": [190, 5000, 800, 10, 350],
    }
)

def display_dataframe_with_single_selection(df):
    options_builder = GridOptionsBuilder.from_dataframe(df)
    options_builder.configure_selection(selection_mode='single', use_checkbox=True)
    grid_options = options_builder.build()
    grid = AgGrid(df, gridOptions=grid_options, width=200, height=300, theme='streamlit', allow_unsafe_jscode=True)
    sel_row = grid['selected_rows']
    return sel_row

selection = display_dataframe_with_single_selection(df)
st.write("Your selection:")
st.write(selection)
1 Like

Streamlit 1.35.0 introduced row and column selections for dataframes. You can specify single- or multi- row/column selections.

3 Likes

Can I use other buttons to change the selected state of the dataframe?

Selection state is read-only, so the native dataframe selection feature can’t be programmatically changed from the backend. :slight_smile:

2024-11-05 9.48.19 a.m.

You can do this with the pandas style API, here’s a demo.

import streamlit as st
import pandas as pd

# Sample DataFrame
@st.cache_data
def load_data():
    data = {
        'A': range(10),
        'B': range(10, 20),
        'C': range(20, 30)
    }
    return pd.DataFrame(data)

df = load_data()
st.title('Highlight DataFrame Rows')

# Function to highlight odd/even rows
def highlight_odd_even(df, odd=True):
    styles = []
    for i in range(len(df)):
        if (i % 2 == 0 and not odd) or (i % 2 == 1 and odd):
            styles.append('background-color: yellow')
        else:
            styles.append('')
    return ['background-color: yellow' if s else '' for s in styles]

highlight_odd = st.button('Highlight Odd Rows')
highlight_even = st.button('Highlight Even Rows')

if highlight_odd:
    styled_df = df.style.apply(highlight_odd_even, odd=True)
    st.dataframe(styled_df)
elif highlight_even:
    styled_df = df.style.apply(highlight_odd_even, odd=False)
    st.dataframe(styled_df)
else:
    st.dataframe(df)
1 Like

add this feature may useful :grinning: