Aggrid and page updates

Hi,

I’ve been trying to make aggrid work with streamlit, and while everything looks great on surface, getting a good user experience seems quite problematic so far. This is probably because of my ignorance, and I’m writing to ask for help with the two problems I’m facing.

The primary problem has to do with updating the page with some filters enabled for aggrid. I’ve a page with 2 displays, a distribution count with a selection box to pick the column for which you want the distribution count, and a dataframe table that’s displaying the data, and is the input to the distribution count. In other words, its like the example shown with the aggrid example, but with filters instead of row selection.

The thing I’d like to do is update the histogram based on the filter selected. But the moment I start typing in a column’s filter, the page reloads and the filter is lost. I’ve tried various tricks without much success. I’m posting the code that shows the issue. The code may look long, but all its doing is essentially:

  • reading a parquet dir with pandas (pick a csv file if you like, the data is irrelevant)
  • drawing the dataframe with aggrid
  • using the filttered rows to display the value counts as a histogram.

Thanks,

Dinesh

import pandas as pd

import streamlit as st
import altair as alt
from st_aggrid import GridOptionsBuilder, AgGrid, GridUpdateMode, JsCode


def draw_aggrid_df(df) -> AgGrid:

    gb = GridOptionsBuilder.from_dataframe(df)
    gb.configure_pagination(paginationPageSize=25)

    gb.configure_default_column(floatingFilter=True, selectable=False)

    gb.configure_grid_options(domLayout='normal')

    gridOptions = gb.build()

    grid_response = AgGrid(
        df,
        gridOptions=gridOptions,
        data_return_mode='FILTERED',
        update_mode=GridUpdateMode.FILTERING_CHANGED,
        theme='streamlit',
        key='dataframe',
    )
    return grid_response

def draw_histogram(show_df):
    '''Display the value counts histogram'''

    dfcols = show_df.columns.tolist()

    uniq_col = st.container()
    dfcols = sorted((filter(lambda x: x not in ['index', 'sqvers'],
                            dfcols)))
    uniq_clicked = '-'
    with uniq_col:
        selindex = 0
        uniq_clicked = st.selectbox(
            'Distribution Count of', options=['-'] + dfcols,
            index=selindex, key='xplore_uniq_col')

    if uniq_clicked != '-':
        uniq_df = df[uniq_clicked] \
            .value_counts() \
            .reset_index() \
            .rename(columns={uniq_clicked: 'numRows',
                             'index': uniq_clicked}) \
            .sort_values(by=['numRows'], ascending=False)
    else:
        uniq_df = pd.DataFrame()

    if uniq_df.empty:
        return

    with uniq_col:
        if uniq_df.shape[0] > 16:
            with uniq_col:
                st.warning(
                    f'{uniq_clicked} has cardinality of '
                    f'{uniq_df.shape[0]}, displaying top 16')
            chart = alt.Chart(
                uniq_df.head(16),
                title=f'{uniq_clicked} Distribution') \
                .mark_bar(color='purple', tooltip=True) \
                .encode(y=alt.Y(f'{uniq_clicked}:N',
                                sort='-x'),
                        x='numRows')
        else:
            chart = alt.Chart(
                uniq_df, title=f'{uniq_clicked} Distribution') \
                .mark_bar(color='purple', tooltip=True) \
                .encode(y=alt.Y(f'{uniq_clicked}:N',
                                sort='-x'),
                        x='numRows')

        st.altair_chart(chart)

if __name__ == '__main__':

    df = pd.read_parquet('/home/ddutt/tmp/demo/bgp')
    uniq_col = st.container()
    ag = draw_aggrid_df(df)
    filtered_df = pd.DataFrame(ag['data'])
    if not filtered_df.empty:
        draw_histogram(filtered_df)
    else:
        draw_histogram(df)