Streamlit Button – The Ultimate Guide with Video : Kevin MacNeel

Streamlit Button – The Ultimate Guide with Video
by: Kevin MacNeel
blow post content copied from  Finxter
click here to view original post


5/5 - (1 vote)

This tutorial will teach you to show you how to style, position, and handle events with the Streamlit button.

It will then show you how to use different types of buttons to create an event-driven low-code user interface to upload, input, download, and filter data that can be graphically tracked as shown in the image below.

Specifically, in this article, you will learn how to 

  • Position Buttons
  • Change Button Styles Color and Size
  • Placing Buttons Side By Side
  • on_click Button Event 
  • Create a Custom Button
  • Use different types of like custom Buttons, Upload Button, Download CSV, and Submit in a Dashboard

Finally, with this knowledge, you will see how a dynamic dashboard was created that uses buttons to input, export, visualize and track data!

Let’s get started!

Positioning Buttons

You can position the button by putting it in other elements. Buttons can also be placed in expanders, sidebars, and columns.

For the expander first, create the expander then set the element below the keyword and put the element below it.

For sidebars, you just need to the with the keyword and to put the element below it. Optionally, you can also just create the button in the sidebar directly like this st.sidebar.button("my button")

The below image shows you two inside an expander element and inside a sidebar. 

# And within an expander
my_expander = st.expander("Expand", expanded=True)
with my_expander:
    clicked = st.button("Expander button")
 
# AND in st.sidebar!
with st.sidebar:
    clicked = st.button("Sidebar button")
st.sidebar.button("my button")

Placing Buttons Side By Side

Columns are another way to position buttons.

Having buttons side by side is easy. First, create the columns. Then put the buttons below the keywords of the different columns.

Below is an example of a custom button called filter and a download button placed side by side using columns. 

col1, col2, col3= st.columns(3)
with col1:
   start_date = st.date_input(
     "Show weights after this date",
     None)
 
   start_date = pd.to_datetime(start_date)
   filter_date_button = st.button('Filter',on_click=save_session)
 
with col2:
  st.write("") #placeholder column
 
with col3:
    if st.download_button(
     label="Download data as CSV",
     data=csv,
     file_name='large_df.csv',
     mime='text/csv',
  ):
     st.write('Energy Data Downloaded')

Changing Button Styles Color and Size

Button color and sizes can be changed by editing the Streamlit themes file. The themes file is called config.toml.

The primary color, background color, secondary background color, text color, and font can all be changed through the file. 

[theme]
primaryColor="#F63366"
backgroundColor="#FFFFFF"
secondaryBackgroundColor="#F0F2F6"
textColor="#262730"
font="sans serif"

The button will be changed to the secondary background color and the color of its name will be the same color as the font. 

You can also change the button size and color by directly injecting CSS styles into the html changes .

First the button class is selected, which is a div, then the button, which is an HTML element. For example   .stButton > button.

Below is an example where the button width, height, color, and background color are all being changed. 

button_style = """
        <style>
        .stButton > button {
            color: blue;
            background: gray;
            width: 100px;
            height: 50px;
        }
        </style>
        """
st.markdown(button_style, unsafe_allow_html=True)

Buttons can be styled individually by selecting the button’s particular element via a CSS selector. This can be seen in the example below. As you can see this can be quite lengthy.

    #root > div:nth-child(1) > div > div > div > div > section.main.css-1v3fvcr.egzxvld1 > div > div:nth-child(1) > div > div.css-ocqkz7.e1tzin5v0 > div:nth-child(1) > div:nth-child(1) > div > div:nth-child(2) > div > button {
        background:#28a745;
        color:white;
       
      }

Creating a Custom Button

Streamlit developers can create custom buttons. A button is simply created by st.button("Click me") and the argument passed in is the button name.

Below is an example.

import streamlit as st
 
button_pressed = st.button("Click Me")
if button_pressed:
    st.write("Button is pressed")

A simple custom button changes its state upon click. The button becomes true once it is clicked.

In the above example, a message will be displayed on the screen once the button is clicked. This custom button has little functionality though, but it can become much more functional once it alters Streamlit’s session_state. The below button alters the session_state once it is clicked.

Onclick button event

def save_session():
   filtered_line_chart = st.session_state['energy_source'].query(
       "Date >= @start_date "
   )
 
filter_date_button = st.button('Filter',on_click=save_session)
filtered_line_chart =  st.session_state['energy_source']

The function for the on_click event is passed to the st.button() function. There just needs to be a function to handle the on_click event.

In this case, the second parameter is passed to the on_click handler and is called every time the button is clicked. In this example every time the button is pressed the save_session function is called. Of note is that the function save_session must come before the button or else the function will be undefined. 

When combined with Streamlit’s session state, custom buttons can be used to run an event and have the data persist after the button is pressed. The session_state variable retains its value throughout posts and clicks. 

Create a Dashboard 

The above dashboard utilizes the examples and concepts explained above.

It also uses some of Streamlit’s built-in buttons like the submit button, the upload button, and the download CSV button. This dashboard can be used to track data of different types like miles ridden on a bike or steps per day. 

The type of data can easily be specified by changing the variable track_data = 'Track My Data' to a specific type of data. An example would be track_data = 'Miles Biked'.

The following libraries need to be installed and imported: streamlit, pandas, Altair.

The source code is stored on Github here. You can view this dashboard on Streamlit here

Program Source Code

import streamlit as st
import pandas as pd
import altair as alt
 
session_key='data_source'
 
track_data = 'Track My Data'
if session_key not in st.session_state:
    data_source = pd.DataFrame({
        "Person": ["Bill","Sally","Bill","Sally","Bill","Sally","Bill","Sally","Bill"],
        track_data:  [15, 10, 30, 13, 8, 70, 17, 83, 70],
        "Date": ["2022-1-23", "2022-1-30", "2022-1-5", "2022-2-21", "2022-2-1", "2022-2-2", "2022-3-1", "2022-3-3", "2022-3-6"]
    })
    data_source['Date'] = pd.to_datetime(data_source['Date'])
    st.session_state[session_key] = data_source
 
 
def save_session():
   filtered_line_chart = st.session_state[session_key].query(
       "Date >= @start_date "
   )
   filtered_line_chart =  st.session_state[session_key]
 
def clear_data():
   st.session_state[session_key]  = pd.DataFrame()
 
 
with st.sidebar.form("my_form"):
    input_person = st.selectbox(
     'Who would you like to enter a ' + track_data + ' for?',
     ('Bill', 'Sally'))
 
    input_weight = st.text_input(track_data + " input")
    input_date = pd.to_datetime(st.date_input("Date input"))
   
 
    # Every form must have a submit button.
    submitted = st.form_submit_button("Submit")
    if submitted:
        data_source = st.session_state[session_key]
       
        data_source = data_source.append({track_data:int(input_weight),"Person":input_person,"Date":  pd.to_datetime(input_date)},ignore_index=True)
       
        st.session_state[session_key] = data_source
 
    uploaded_file = st.file_uploader("Choose a file")
    if uploaded_file is not None:
     # To read file as bytes:
      bytes_data = uploaded_file.getvalue()
      st.write(bytes_data)
 
     
      dataframe = pd.read_csv(uploaded_file)
      st.write(dataframe)
 
def convert_df(df):
     # IMPORTANT: Cache the conversion to prevent computation on every rerun
     return df.to_csv().encode('utf-8')
 
csv = convert_df(st.session_state[session_key])      
   
 
col1, col2, col3= st.columns(3)
with col1:
   start_date = st.date_input(
     "Show " + track_data + " after this date",
     None)
 
   start_date = pd.to_datetime(start_date)
   filter_date_button = st.button('Filter',on_click=save_session)
 
 
with col2:
  st.write("")
 
 
with col3:
    if st.download_button(
     label="Download data as CSV",
     data=csv,
     file_name=track_data + "_records.csv",
     mime='text/csv',
    ):
     st.write(' Data Downloaded')
    clear_data = st.button("Clear Data", on_click=clear_data)
 
 
if filter_date_button:
  filtered_line_chart =  st.session_state[session_key].query(
    "Date >= @start_date ")
else:
  filtered_line_chart = st.session_state[session_key]
 
if not st.session_state[session_key].empty:
  line_chart = alt.Chart(filtered_line_chart).mark_line().encode(
        y=  alt.Y(track_data, title=track_data),
        x=  alt.X( 'Date', title='Month'),
       color='Person'
  ).properties(
        height=400, width=700,
        title=track_data + " Chart"
    ).configure_title(
        fontSize=16
    )
  st.altair_chart(line_chart, use_container_width=True)
else:
    st.write("All Data has been cleared")
 

The above code uses the following buttons to create its functionality.

Submit Button

The submit button is used to enter new data that will be graphed by the line chart.

It adds items that have the form fields of numerical data, person, and date. 

The data frame is stored in the session state.

The submit button is a built-in button to Streamlit that one can use to submit form data.

The below code creates the submit button by submitted = st.form_submit_button("Submit").

The submitted value is checked to see if the form has been submitted. Upon submission, the data entered will be graphed in the line graph. 

Upload Button

The next button is another built-in button called the Upload button.

This can be used to upload data to the session state. It will overwrite the existing data. The data will then be graphed in the line chart.

To create the upload button enter this code uploaded_file = st.file_uploader("Choose a file"). The uploaded file can be checked if uploaded_file is true to determine if a file has been uploaded.

Download Button

The download button is used to create the CSV. The code for it is 

    st.download_button(
     label="Download data as CSV",
     data=csv,
     file_name=track_data + "_records.csv",
     mime='text/csv',
    )

Custom Button

The first custom button that is created is the custom Filter button.

This button has an onclick event that calls the function save_session. This saves a data frame that is filtered by the date that is entered in the input box in session_state.

The code for the filter button looks like this 

filter_date_button = st.button('Filter',on_click=save_session) 

It calls in the on_click event this function

def save_session():
   filtered_line_chart = st.session_state[session_key].query(
       "Date >= @start_date "
   )
   filtered_line_chart =  st.session_state[session_key]

The next custom button clear data is used to make the data frame empty and to store this variable in the session_state.  It also has an onclick event.

It’s code looks like this 

def clear_data():
   st.session_state[session_key]  = pd.DataFrame()


clear_data = st.button("Clear Data", on_click=clear_data) 

Conclusion

This article has shown the different configurations, functionality, and aspects of using Streamlit buttons.

Then you learned how to create a full dashboard that utilized custom and built-in buttons in a dashboard to track and graph a person’s data. 

Have fun creating great dynamic user interfaces with Streamlit buttons!



July 09, 2022 at 01:49PM
Click here for more details...

=============================
The original post is available in Finxter by Kevin MacNeel
this post has been published as it is through automation. Automation script brings all the top bloggers post under a single umbrella.
The purpose of this blog, Follow the top Salesforce bloggers and collect all blogs in a single place through automation.
============================

Salesforce