Notes on the Streamlit API
- Overview
- Streamlit
- Magic Commands
- Display Text
- Display Data
- Display Charts
- Display Media
- Add Widgets to Sidebar
- Columns
- Control Flow
- Display Interactive Widgets
- Command Line
- Mutate Data
- Display and Execute Code
- Placeholders, help, and options
- Page Configuration
- Cache Data Objects
- Cache Non-data Objects
- Display Progress and Status
Overview
Here are some notes and reference code for working with the Streamlit API.
Streamlit
Turns data scripts into shareable web apps
pip install streamlit
Test Installation:
streamlit hello
Run apps:
streamlit run main.py
Format text using Markdown
Magic Commands
replit: https://replit.com/@innominate817/streamlit-magic-commands#main.py
import streamlit as st
import pandas as pd
= {'col1': [1,2], 'col2': [3,4]}
d = pd.DataFrame(data=d)
data
# Magic commands implicitly call st.write()
'_This_ is some **Markdown***'
= 3
num 'dataframe:', data
Display Text
replit: https://replit.com/@innominate817/streamlit-display-text#main.py
import streamlit as st
'Fixed width text')
st.text('_Markdown_') # see *
st.markdown('Balloons. Hundreds of them...')
st.caption(r''' e^{i\pi} + 1 = 0 ''')
st.latex('Most objects') # df, err, func, keras!
st.write('st', 'is <', 3]) # see *
st.write(['My title')
st.title('My header')
st.header('My sub')
st.subheader('for i in range(8): foo()') st.code(
Display Data
replit: https://replit.com/@innominate817/streamlit-display-data
import streamlit as st
import pandas as pd
= [{
d 'a': 1,
'b': 2,
'c': 3,
'd': 4
}, {'a': 100,
'b': 200,
'c': 300,
'd': 400
}, {'a': 1000,
'b': 2000,
'c': 3000,
'd': 4000
}]= pd.DataFrame(data=d)
data
st.dataframe(data)0:2])
st.table(data.iloc['foo': 'bar', 'fu': 'ba'})
st.json({="Temp", value="273 K", delta="1.2 K") st.metric(label
Display Charts
replit #1: https://replit.com/@innominate817/streamlit-display-charts#main.py
import streamlit as st
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import altair as alt
import plotly.figure_factory as ff
from bokeh.plotting import figure
= pd.DataFrame(np.random.randn(20, 3), columns=['a', 'b', 'c'])
chart_data
st.line_chart(chart_data)
= pd.DataFrame(np.random.randn(20, 3), columns=['a', 'b', 'c'])
chart_data
st.area_chart(chart_data)
= pd.DataFrame(np.random.randn(50, 3), columns=["a", "b", "c"])
chart_data
st.bar_chart(chart_data)
= np.random.normal(1, 1, size=100)
arr = plt.subplots()
fig, ax =20)
ax.hist(arr, bins
st.pyplot(fig)
= pd.DataFrame(np.random.randn(200, 3), columns=['a', 'b', 'c'])
df
= alt.Chart(df).mark_circle().encode(x='a',
c ='b',
y='c',
size='c',
color=['a', 'b', 'c'])
tooltip
=True)
st.altair_chart(c, use_container_width
= pd.DataFrame(np.random.randn(200, 3), columns=['a', 'b', 'c'])
df
st.vega_lite_chart(
df, {'mark': {
'type': 'circle',
'tooltip': True
},'encoding': {
'x': {
'field': 'a',
'type': 'quantitative'
},'y': {
'field': 'b',
'type': 'quantitative'
},'size': {
'field': 'c',
'type': 'quantitative'
},'color': {
'field': 'c',
'type': 'quantitative'
},
},
})
# Add histogram data
= np.random.randn(200) - 2
x1 = np.random.randn(200)
x2 = np.random.randn(200) + 2
x3
# Group data together
= [x1, x2, x3]
hist_data
= ['Group 1', 'Group 2', 'Group 3']
group_labels
# Create distplot with custom bin_size
= ff.create_distplot(hist_data, group_labels, bin_size=[.1, .25, .5])
fig
# Plot!
=True)
st.plotly_chart(fig, use_container_width
= [1, 2, 3, 4, 5]
x = [6, 7, 2, 4, 5]
y
= figure(title='simple line example', x_axis_label='x', y_axis_label='y')
p
='Trend', line_width=2)
p.line(x, y, legend_label
=True) st.bokeh_chart(p, use_container_width
replit #2: https://replit.com/@innominate817/streamlit-display-charts-2#main.py
import streamlit as st
import pandas as pd
import numpy as np
import pydeck as pdk
import graphviz as graphviz
= pd.DataFrame(np.random.randn(1000, 2) / [50, 50] + [37.76, -122.4],
df =['lat', 'lon'])
columns
st.pydeck_chart(
pdk.Deck(='mapbox://styles/mapbox/light-v9',
map_style=pdk.ViewState(
initial_view_state=37.76,
latitude=-122.4,
longitude=11,
zoom=50,
pitch
),=[
layers
pdk.Layer('HexagonLayer',
=df,
data='[lon, lat]',
get_position=200,
radius=4,
elevation_scale=[0, 1000],
elevation_range=True,
pickable=True,
extruded
),
pdk.Layer('ScatterplotLayer',
=df,
data='[lon, lat]',
get_position='[200, 30, 0, 160]',
get_color=200,
get_radius
),
],
))
# Create a graphlib graph object
= graphviz.Digraph()
graph 'run', 'intr')
graph.edge('intr', 'runbl')
graph.edge('runbl', 'run')
graph.edge('run', 'kernel')
graph.edge('kernel', 'zombie')
graph.edge('kernel', 'sleep')
graph.edge('kernel', 'runmem')
graph.edge('sleep', 'swap')
graph.edge('swap', 'runswap')
graph.edge('runswap', 'new')
graph.edge('runswap', 'runmem')
graph.edge('new', 'runmem')
graph.edge('sleep', 'runmem')
graph.edge(
st.graphviz_chart(graph)
= pd.DataFrame(np.random.randn(1000, 2) / [50, 50] + [37.76, -122.4],
df =['lat', 'lon'])
columnsmap(df) st.
Display Media
replit: https://replit.com/@innominate817/streamlit-display-media#main.py
Note: audio does not seem to pass through in replit
import streamlit as st
from PIL import Image
= Image.open('sunrise.jpg')
image ='Sunrise by the mountains')
st.image(image, caption
= open('audio_sample.mp3', 'rb')
audio_file = audio_file.read()
audio_bytes format='audio/mp3')
st.audio(audio_bytes,
= open('video_sample.mp4', 'rb')
video_file = video_file.read()
video_bytes st.video(video_bytes)
Columns
replit: https://replit.com/@innominate817/streamlit-columns#main.py
import streamlit as st
= st.columns(3)
col1, col2, col3
with col1:
"A cat")
st.header("https://images.pexels.com/photos/1170986/pexels-photo-1170986.jpeg?cs=srgb&dl=pexels-evg-culture-1170986.jpg&fm=jpg&w=640&h=960")
st.image(
with col2:
"A dog")
st.header("https://images.pexels.com/photos/2252311/pexels-photo-2252311.jpeg?cs=srgb&dl=pexels-laura-stanley-2252311.jpg&fm=jpg&w=640&h=959")
st.image(
with col3:
"An owl")
st.header("https://images.pexels.com/photos/5883285/pexels-photo-5883285.jpeg?cs=srgb&dl=pexels-mehmet-turgut-kirkgoz-5883285.jpg&fm=jpg&w=640&h=960") st.image(
Control Flow
replit: https://replit.com/@innominate817/streamlit-control-flow#main.py
import streamlit as st
= st.text_input('Name')
name if not name:
'Please input a name.')
st.warning(
st.stop()'Thank you for inputting a name.')
st.success(
with st.form("my_form"):
"Inside the form")
st.write(= st.slider("Form slider")
slider_val = st.checkbox("Form checkbox")
checkbox_val
# Every form must have a submit button.
= st.form_submit_button("Submit")
submitted if submitted:
"slider", slider_val, "checkbox", checkbox_val)
st.write(
"Outside the form") st.write(
Display Interactive Widgets
replit: https://replit.com/@innominate817/streamlit-interactive-widgets#main.py
import streamlit as st
import numpy as np
import pandas as pd
import io
"Button")
st.header(if st.button('Say hello'):
'Why hello there')
st.write(else:
'Goodbye')
st.write(
"Download Buttons")
st.header(= pd.DataFrame(np.random.randn(200, 3), columns=['a', 'b', 'c'])
df
@st.cache
def convert_df(df):
# IMPORTANT: Cache the conversion to prevent computation on every rerun
return df.to_csv().encode('utf-8')
= convert_df(df)
csv
st.download_button(="Download data as CSV",
label=csv,
data='large_df.csv',
file_name='text/csv',
mime
)
= '''This is some text'''
text_contents 'Download some text', text_contents)
st.download_button(
= b'example content'
binary_contents # Defaults to 'application/octet-stream'
'Download binary file', binary_contents)
st.download_button(
with open("flower.jpg", "rb") as file:
= st.download_button(label="Download image",
btn =file,
data="flower.png",
file_name="image/png")
mime
"Checkbox")
st.header(= st.checkbox('I agree')
agree
if agree:
'Great!')
st.write(
"Radio Button")
st.header(= st.radio("What's your favorite movie genre",
genre 'Comedy', 'Drama', 'Documentary'))
(
if genre == 'Comedy':
'You selected comedy.')
st.write(else:
"You didn't select comedy.")
st.write(
"Selectbox")
st.header(= st.selectbox('How would you like to be contacted?',
option 'Email', 'Home phone', 'Mobile phone'))
(
'You selected:', option)
st.write(
"Multiselect")
st.header(= st.multiselect('What are your favorite colors',
options_multi 'Green', 'Yellow', 'Red', 'Blue'],
['Yellow', 'Red'])
[
'You selected:', options_multi)
st.write(
"Sliders")
st.header('Basic')
st.subheader('Slide me', min_value=0, max_value=10)
st.slider('Range Slider')
st.subheader(= st.slider('Select a range of values', 0.0, 100.0, (25.0, 75.0))
values 'Values:', values)
st.write(
'Range Time Slider')
st.subheader(from datetime import time
= st.slider("Schedule your appointment:",
appointment =(time(11, 30), time(12, 45)))
value"You're scheduled for:", appointment)
st.write(
'Datetime Slider')
st.subheader(from datetime import datetime
= st.slider("When do you start?",
start_time =datetime(2020, 1, 1, 9, 30),
valueformat="MM/DD/YY - hh:mm")
"Start time:", start_time)
st.write(
"Select Sliders")
st.header(= st.select_slider(
color 'Select a color of the rainbow',
=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'])
options'My favorite color is', color)
st.write(
= st.select_slider(
start_color, end_color 'Select a range of color wavelength',
=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'],
options=('red', 'blue'))
value'You selected wavelengths between', start_color, 'and', end_color)
st.write(
"Text Input")
st.header(= st.text_input('Movie title', 'Life of Brian')
title 'The current movie title is', title)
st.write(
"Number Input")
st.header(= st.number_input('Insert a number')
number 'The current number is ', number)
st.write(
"Text Area")
st.header(= st.text_area(
txt 'Text to analyze', '''
It was the best of times, it was the worst of times, it was
the age of wisdom, it was the age of foolishness, it was
the epoch of belief, it was the epoch of incredulity, it
was the season of Light, it was the season of Darkness, it
was the spring of hope, it was the winter of despair, (...)
''')
'First word:', txt.split(',')[0:2])
st.write(
"Date Input")
st.header(from datetime import date
= st.date_input("When's your birthday", date(2019, 7, 6))
d 'Your birthday is:', d)
st.write(
"Time Input")
st.header(= st.time_input('Set an alarm for', time(8, 45))
t 'Alarm is set for', t)
st.write(
"File Uploader")
st.header("Single File")
st.subheader(= st.file_uploader("Choose a file")
uploaded_file if uploaded_file is not None:
# To read file as bytes:
= uploaded_file.getvalue()
bytes_data
st.write(bytes_data)
# To convert to a string based IO:
= io.StringIO(uploaded_file.getvalue().decode("utf-8"))
stringio
st.write(stringio)
# To read file as string:
= stringio.read()
string_data
st.write(string_data)
# Can be used wherever a "file-like" object is accepted:
= pd.read_csv(uploaded_file)
dataframe
st.write(dataframe)"Multiple Files")
st.subheader(= st.file_uploader("Choose a CSV file",
uploaded_files =True)
accept_multiple_filesfor uploaded_file in uploaded_files:
= uploaded_file.read()
bytes_data "filename:", uploaded_file.name)
st.write(
st.write(bytes_data)
"Color Picker")
st.header(= st.color_picker('Pick A Color', '#00f900')
color 'The current color is', color) st.write(
Command Line
streamlit --help
streamlit run your_script.py
streamlit hello
streamlit config show
streamlit cache clear
streamlit docs
streamlit --version
Mutate Data
replit: https://replit.com/@innominate817/streamlit-mutate-data#main.py
import streamlit as st
import pandas as pd
import numpy as np
"Mutate Table")
st.header(= pd.DataFrame(np.random.randn(50, 20),
df1 =('col %d' % i for i in range(20)))
columns
= st.table(df1)
my_table
= pd.DataFrame(np.random.randn(50, 20),
df2 =('col %d' % i for i in range(20)))
columns
my_table.add_rows(df2)# Now the table shown in the Streamlit app contains the data for
# df1 followed by the data for df2.
"Mutate Chart")
st.header(# Assuming df1 and df2 from the example above still exist...
= st.line_chart(df1)
my_chart
my_chart.add_rows(df2)# Now the chart shown in the Streamlit app contains the data for
# df1 followed by the data for df2.
Display and Execute Code
replit: https://replit.com/@innominate817/streamlit-echo-code#main.py
import streamlit as st
with st.echo():
'This code will be printed')
st.write(= 2 + 2
num f'Sum: {num}') st.write(
Placeholders, help, and options
replit: https://replit.com/@innominate817/streamlit-placeholders-help-options#main.py
import streamlit as st
import pandas as pd
import numpy as np
='wide')
st.set_page_config(layout
# Replace any single element.
= st.empty()
element = pd.DataFrame(np.random.randn(20, 3), columns=['a', 'b', 'c'])
chart_data
element.line_chart(chart_data)"New Text") # Replaces previous.
element.text_input(
# Insert out of order.
= st.container()
elements
elements.line_chart(chart_data)"Hello")
st.write("Some more new text") # Appears above "Hello".
elements.text_input(
help(pd.DataFrame) st.
Page Configuration
replit: https://replit.com/@innominate817/streamlit-page-configuration#main.py
import streamlit as st
="Ex-stream-ly Cool App",
st.set_page_config(page_title="š§",
page_icon="wide",
layout="expanded",
initial_sidebar_state={
menu_items'Get Help':
'https://www.extremelycoolapp.com/help',
'Report a bug':
"https://www.extremelycoolapp.com/bug",
'About':
"# This is a header. This is an *extremely* cool app!"
})
Cache Data Objects
import streamlit
import pandas as pd
import numpy as np
# E.g. Dataframe computation, storing downloaded data, etc.
@st.experimental_memo
def foo(bar):
# Do something expensive and return data
= pd.DataFrame(np.random.randn(20, 3), columns=['a', 'b', 'c'])
chart_data return chart_data
# Executes foo
= foo(ref1)
d1 # Does not execute foo
# Returns cached item by value, d1 == d2
= foo(ref1)
d2 # Different arg, so function foo executes
= foo(ref2) d3
Cache Non-data Objects
import streamlit as st
# E.g. TensorFlow session, database connection, etc.
@st.experimental_singleton
def foo(bar):
# Create and return a non-data object
return session
# Executes foo
= foo(ref1)
s1 # Does not execute foo
# Returns cached item by reference, d1 == d2
= foo(ref1)
s2 # Different arg, so function foo executes
= foo(ref2) s3
Display Progress and Status
replit: https://replit.com/@innominate817/streamlit-display-progress-and-status#main.py
import streamlit as st
import time
with st.spinner('Wait for it...'):
5)
time.sleep('Done!')
st.success(
= st.progress(0)
my_bar
for percent_complete in range(100):
0.1)
time.sleep(+ 1)
my_bar.progress(percent_complete
st.balloons()
'Error message')
st.error(
'Warning message')
st.warning(
'Info message')
st.info(
'Success message')
st.success(
= RuntimeError('This is an exception of type RuntimeError')
e st.exception(e)
References:
Iām Christian Mills, a deep learning consultant specializing in practical AI implementations. I help clients leverage cutting-edge AI technologies to solve real-world problems.
Interested in working together? Fill out my Quick AI Project Assessment form or learn more about me.