How to dynamically pick the columns to show in dataframe with streamlit

I am trying to pick the columns to show dynamically in a streamlit dataframe.

Below is the code

#! /usr/bin/env python3
import streamlit as st
import pandas as pd

st.set_page_config(layout="wide")

# Create a sample dataframe with 3 columns Col1, Col2, Col3
df = pd.DataFrame({
    'Col1': ['A', 'B', 'C'],
    'Col2': ['X', 'Y', 'Z'],
    'Col3': [1, 2, 3]
})

#  Have a dropdown to select a column among Col1, Col2
col = st.selectbox('Select a column', ['Col1', 'Col2'])

# Show the dataframe with the selected column and column Col3
st.dataframe(df, column_order=[col, 'Col3'], use_container_width=True)

The issue is, irrespective of the selection, it always shows Col1 and Col3 always.
As far as I can imagine, this might be because column_order is frozen when the dataframe is created the first time. But is this the intended behavior?

The following code works dynamically to disable the dropdown based on checkbox, like its shown in examples.

disable = st.checkbox('Disable the dropdown')
sel = st.selectbox('Select a column', ['Col1', 'Col2'], key='sel', disabled=disable)

Why is column_order different?

I even tried using tuple to check if any python-mutable stuff is happening under the hood. But the behavior is same.

st.dataframe(df, column_order=(col, 'Col3'), use_container_width=True)

Am I missing something?

Ok, I’m not entirely sure, but I have a suggestion that could probably work

In terms of the order of operations here, the first run through of the code sets col = Col1 based on the default from this:

col = st.selectbox('Select a column', ['Col1', 'Col2'])

Then when you change that selectbox, it re-runs the code top to bottom. I thought the selectbox would maintain its state without specifically defining it (so if you chose ‘Col2’ it would stay that way), but that seems to not be the case here. So, you can add a key to set the results of the user selection to maintain its state when the page re-runs, such as:

col = st.selectbox('Select a column', ['Col1', 'Col2'], key='selected_col')

If that doesn’t work, please feel free to follow up here. I have some thoughts on next steps, but they are slightly more complex / less intuitive

Your code works as expected in streamlit 1.41, but not in 1.42. The new behavior doesn’t look right to me so I assume it is a regression.

As a workaround, pass only the selected data to st.dataframe:

st.dataframe(df[[col, "Col3"]])

Note that specifying the column order neither works in this case.

1 Like

I just happened to realise the same, thank you.

It works me if I use static names for column_order, since it ignores the missing columns anyway.

Thank you for the confirmation

Reported at Dynamic variable in column_order does not work with 1.42 works with 1.41 · Issue #10442 · streamlit/streamlit

1 Like