Display Output after selection from two dropdown menus

I am new to python streamlit package and I have data that I have created 2 dropdown menus. One dropdown menu selects hospital name and another select document source. Here is how my data looks like:

import pandas as pd

df = pd.DataFrame({'Hospital': ['Nick hospital', 'Nick hospital', 'Nick hospital',
                                'Krish hospital', 'Krish hospital', 'Krish hospital'],
                   'document_source': ['NAR', 'PAR', 'Free Text', 'NAR', 'PAR', 'Free Text'],
                   'document_count': [1200, 150, 3, 2500, 342, 300]})
df.head()

Now I want to display document count after hospital and document source has been selected.Here is my streamlit code creating dropdowns

import streamlit as st
#create sidebar
st.sidebar.title("Filter data")

temp = df.to_dict('list')
temp['Hospital'] = list(set(temp['Hospital']))
temp['document_source'] = list(set(temp['document_source']))
temp_records = df.to_dict('records')

#Checkbox for Hospitals
hosp_list = st.sidebar.selectbox("Select Hospital", temp['Hospital'])


#Chech box for Documents
doc_source = st.sidebar.selectbox("Select Document source", temp['document_source'])

st.subheader('Document Count')

Expected output is to show document count per hospital selected. so If I select a hospital and select document source I should get the document count of that document in bold blue colour. could someone out there help please

Hello @Livingstone90, welcome to the forums :tada:

  • On the question of fetching data inside Pandas, you can use one of the following two methods :
# using selecting in dataframe - https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#different-choices-for-indexing
# .loc[r, c] -> r being query on rows to filter Hospital and document_source, c being column you want to keep 
# .iloc[0] to get content of cell in first row
count = df.loc[(df["Hospital"] == hosp_list) & (df["document_source"] == doc_source), 'document_count'].iloc[0]

# if you want to visualize the dataframe after filtering
# st.dataframe(df[(df["Hospital"] == hosp_list) & (df["document_source"] == doc_source)])

# using query SQL like - https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html
count_2 = df.query(f"Hospital=='{hosp_list}' & document_source=='{doc_source}'")['document_count'].iloc[0]
  • to display the count in blue bold, this is not exactly Streamlit native, we instead pass some CSS inside Markdown like the following :
st.markdown(f"<span style='color: blue;font-size: 24px;font-weight: bold;'>{count}</span>", unsafe_allow_html=True)

Some more tips I wanted to share :

  • each time you select an item from the selectbox, all your script is rerun, so you will recreate the same data at each select. This is OK given the size of the current dataframe but if you are going to load bigger files as a next step, it is better to cache the data so it is saved by Streamlit for reuse
@st.cache
def load_data():
    return pd.DataFrame({'Hospital': ['Nick hospital', 'Nick hospital', 'Nick hospital',
                                'Krish hospital', 'Krish hospital', 'Krish hospital'],
                   'document_source': ['NAR', 'PAR', 'Free Text', 'NAR', 'PAR', 'Free Text'],
                   'document_count': [1200, 150, 3, 2500, 342, 300]})

df = load_data()
  • to get the list of unique elemnts in a column, df["Hospital"].unique() is clean and clear :wink:

so the script at the end :

import pandas as pd
import streamlit as st

@st.cache
def load_data():
    df = pd.DataFrame({'Hospital': ['Nick hospital', 'Nick hospital', 'Nick hospital',
                                'Krish hospital', 'Krish hospital', 'Krish hospital'],
                   'document_source': ['NAR', 'PAR', 'Free Text', 'NAR', 'PAR', 'Free Text'],
                   'document_count': [1200, 150, 3, 2500, 342, 300]})
    return df

df = load_data()

st.sidebar.title("Filter data")

#Checkbox for Hospitals
hosp_list = st.sidebar.selectbox("Select Hospital", df["Hospital"].unique())

#Chech box for Documents
doc_source = st.sidebar.selectbox("Select Document source", df["document_source"].unique())

st.subheader('Document Count')

count = df.loc[(df["Hospital"] == hosp_list) & (df["document_source"] == doc_source), 'document_count'].iloc[0]
count_2 = df.query(f"Hospital=='{hosp_list}' & document_source=='{doc_source}'")['document_count'].iloc[0]

st.markdown(f"<span style='color: blue;font-size: 24px;font-weight: bold;'>{count}</span>", unsafe_allow_html=True)
st.markdown(f"<span style='color: blue;font-size: 24px;font-weight: bold;'>{count_2}</span>", unsafe_allow_html=True)

Don’t hesitate if you have more questions !

2 Likes

@andfanilo A question sir, so what if a document count is empty? like I select a document source the maybe value of document count is empty, could you edit the code also to cover empty document count fields, like if document count is empty it should display ‘None’