Streamlit - Build Data Apps
1. Giới thiệu Streamlit
Streamlit biến Python scripts thành web apps chỉ trong vài phút!
| Feature | Streamlit |
|---|---|
| Học dễ | ⭐⭐⭐⭐⭐ Cực dễ |
| No frontend | ✅ Chỉ cần Python |
| Hot reload | ✅ Auto refresh |
| Widgets | ✅ Buttons, sliders, inputs |
| Charts | ✅ Plotly, Matplotlib, Altair |
| Deploy | ✅ Streamlit Cloud (free) |
Bash
1# Cài đặt2pip install streamlit3 4# Chạy app5streamlit run app.py2. Hello World App
Python
1# app.py2import streamlit as st34st.title("Hello Streamlit! 👋")5st.write("This is my first Streamlit app")67# Text elements8st.header("This is a header")9st.subheader("This is a subheader")10st.text("Fixed width text")11st.markdown("**Bold** and *italic* text")12st.caption("Small caption text")1314# Code15st.code("print('Hello World')", language="python")1617# LaTeX18st.latex(r"E = mc^2")3. Input Widgets
3.1 Text Input
Python
1import streamlit as st23# Text input4name = st.text_input("Enter your name", "MinAI")5st.write(f"Hello, {name}!")67# Text area8description = st.text_area("Description", "Enter text here...")910# Number input11age = st.number_input("Age", min_value=0, max_value=120, value=25)1213# Password14password = st.text_input("Password", type="password")3.2 Selection Widgets
Python
1# Selectbox2option = st.selectbox(3 "Choose a color",4 ["Red", "Green", "Blue"]5)67# Multiselect8options = st.multiselect(9 "Select fruits",10 ["Apple", "Banana", "Cherry", "Date"],11 ["Apple", "Banana"] # Default12)1314# Radio15choice = st.radio(16 "Pick one",17 ["Option 1", "Option 2", "Option 3"]18)1920# Checkbox21agree = st.checkbox("I agree to terms")22if agree:23 st.write("Thanks for agreeing!")3.3 Sliders và Date Input
Python
1# Slider2value = st.slider("Select value", 0, 100, 50)34# Range slider5values = st.slider("Select range", 0.0, 100.0, (25.0, 75.0))67# Date input8date = st.date_input("Select date")910# Time input 11time = st.time_input("Select time")1213# Color picker14color = st.color_picker("Pick a color", "#00f900")3.4 Buttons
Python
1# Button2if st.button("Click me!"):3 st.write("Button clicked!")45# Download button6st.download_button(7 label="Download CSV",8 data="col1,col2\n1,2\n3,4",9 file_name="data.csv",10 mime="text/csv"11)1213# File uploader14uploaded_file = st.file_uploader("Choose a file", type=["csv", "xlsx"])15if uploaded_file:16 df = pd.read_csv(uploaded_file)17 st.dataframe(df)4. Display Data
4.1 DataFrames
Python
1import streamlit as st2import pandas as pd3import numpy as np45# Sample data6df = pd.DataFrame({7 "Name": ["Alice", "Bob", "Charlie"],8 "Age": [25, 30, 35],9 "Salary": [50000, 60000, 70000]10})1112# Display as static table13st.table(df)1415# Display as interactive dataframe16st.dataframe(df)1718# Editable dataframe19edited_df = st.data_editor(df)2021# With styling22st.dataframe(df.style.highlight_max(axis=0))2324# Metrics25col1, col2, col3 = st.columns(3)26col1.metric("Revenue", "$10,000", "+5%")27col2.metric("Users", "1,234", "-2%")28col3.metric("Rating", "4.5", "+0.2")4.2 Charts
Python
1import streamlit as st2import pandas as pd3import numpy as np45# Sample data6chart_data = pd.DataFrame(7 np.random.randn(20, 3),8 columns=["A", "B", "C"]9)1011# Line chart12st.line_chart(chart_data)1314# Area chart15st.area_chart(chart_data)1617# Bar chart18st.bar_chart(chart_data)1920# Scatter chart (Streamlit native)21st.scatter_chart(chart_data, x="A", y="B")4.3 Plotly Charts
Python
1import streamlit as st2import plotly.express as px34# Plotly charts5df = px.data.gapminder().query("year == 2007")6fig = px.scatter(df, x="gdpPercap", y="lifeExp", 7 color="continent", size="pop",8 hover_name="country", log_x=True)910st.plotly_chart(fig, use_container_width=True)4.4 Matplotlib/Seaborn
Python
1import streamlit as st2import matplotlib.pyplot as plt3import seaborn as sns45# Matplotlib6fig, ax = plt.subplots()7ax.plot([1, 2, 3, 4], [1, 4, 2, 3])8ax.set_title("Simple Plot")9st.pyplot(fig)1011# Seaborn12tips = sns.load_dataset("tips")13fig, ax = plt.subplots()14sns.histplot(tips["total_bill"], ax=ax)15st.pyplot(fig)5. Layout
5.1 Columns
Python
1import streamlit as st23# Equal columns4col1, col2, col3 = st.columns(3)56with col1:7 st.header("Column 1")8 st.write("Content here")910with col2:11 st.header("Column 2")12 st.image("https://picsum.photos/200")1314with col3:15 st.header("Column 3")16 st.button("Click")1718# Custom widths19col1, col2 = st.columns([2, 1]) # 2:1 ratio5.2 Tabs
Python
1tab1, tab2, tab3 = st.tabs(["📈 Chart", "🗃 Data", "📝 About"])23with tab1:4 st.header("Charts")5 st.line_chart([1, 2, 3, 4])67with tab2:8 st.header("Data")9 st.dataframe(df)1011with tab3:12 st.header("About")13 st.write("This is the about section")5.3 Expander và Container
Python
1# Expander2with st.expander("Click to expand"):3 st.write("Hidden content here")4 st.image("https://picsum.photos/300")56# Container7with st.container():8 st.write("This is inside a container")9 10# Empty placeholder11placeholder = st.empty()12placeholder.text("This will be replaced")13placeholder.write("New content!")5.4 Sidebar
Python
1# Sidebar2st.sidebar.title("Settings")3option = st.sidebar.selectbox("Select option", ["A", "B", "C"])4value = st.sidebar.slider("Value", 0, 100, 50)56# With form7with st.sidebar.form("my_form"):8 name = st.text_input("Name")9 submitted = st.form_submit_button("Submit")10 if submitted:11 st.write(f"Hello {name}")6. State Management
Python
1import streamlit as st23# Session state4if 'count' not in st.session_state:5 st.session_state.count = 067# Increment button8if st.button('Increment'):9 st.session_state.count += 11011st.write(f"Count: {st.session_state.count}")1213# Reset button14if st.button('Reset'):15 st.session_state.count = 07. Caching
Python
1import streamlit as st2import pandas as pd34# Cache data (không chạy lại khi có input khác thay đổi)5@st.cache_data6def load_data(url):7 """Load data - chỉ chạy 1 lần"""8 return pd.read_csv(url)910# Cache resource (database connections, ML models)11@st.cache_resource12def load_model():13 """Load ML model - chỉ chạy 1 lần"""14 import pickle15 with open("model.pkl", "rb") as f:16 return pickle.load(f)1718# Sử dụng19df = load_data("data.csv") # Cached!20model = load_model() # Cached!8. Complete Dashboard Example
Python
1# dashboard.py2import streamlit as st3import pandas as pd4import plotly.express as px56# Page config7st.set_page_config(8 page_title="Sales Dashboard",9 page_icon="📊",10 layout="wide"11)1213# Title14st.title("📊 Sales Dashboard")15st.markdown("---")1617# Load data18@st.cache_data19def load_data():20 # Sample data21 return pd.DataFrame({22 'Date': pd.date_range('2024-01-01', periods=100),23 'Sales': np.random.randint(100, 1000, 100),24 'Region': np.random.choice(['North', 'South', 'East', 'West'], 100),25 'Product': np.random.choice(['A', 'B', 'C'], 100)26 })2728df = load_data()2930# Sidebar filters31st.sidebar.header("Filters")32regions = st.sidebar.multiselect(33 "Select Region",34 options=df['Region'].unique(),35 default=df['Region'].unique()36)37products = st.sidebar.multiselect(38 "Select Product",39 options=df['Product'].unique(),40 default=df['Product'].unique()41)4243# Filter data44df_filtered = df[45 (df['Region'].isin(regions)) & 46 (df['Product'].isin(products))47]4849# KPIs50col1, col2, col3, col4 = st.columns(4)51col1.metric("Total Sales", f"${df_filtered['Sales'].sum():,.0f}")52col2.metric("Avg Sales", f"${df_filtered['Sales'].mean():,.0f}")53col3.metric("Max Sales", f"${df_filtered['Sales'].max():,.0f}")54col4.metric("Transactions", f"{len(df_filtered):,}")5556st.markdown("---")5758# Charts59col1, col2 = st.columns(2)6061with col1:62 st.subheader("Sales by Region")63 fig = px.pie(df_filtered, values='Sales', names='Region', hole=0.4)64 st.plotly_chart(fig, use_container_width=True)6566with col2:67 st.subheader("Sales Trend")68 daily_sales = df_filtered.groupby('Date')['Sales'].sum().reset_index()69 fig = px.line(daily_sales, x='Date', y='Sales')70 st.plotly_chart(fig, use_container_width=True)7172# Data table73st.subheader("Raw Data")74st.dataframe(df_filtered, use_container_width=True)7576# Download77csv = df_filtered.to_csv(index=False)78st.download_button("Download CSV", csv, "sales_data.csv", "text/csv")9. Deploy to Streamlit Cloud
9.1 Chuẩn bị files
Text
1my_app/2├── app.py # Main app3├── requirements.txt # Dependencies4└── .streamlit/5 └── config.toml # Config (optional)9.2 requirements.txt
Text
1streamlit2pandas3plotly4numpy9.3 Deploy
- Push code lên GitHub
- Vào share.streamlit.io
- Connect GitHub repo
- Select
app.py - Click "Deploy"
10. Best Practices
Python
1# 1. Use page config2st.set_page_config(page_title="My App", layout="wide")34# 2. Cache expensive operations5@st.cache_data6def load_data():7 return pd.read_csv("large_file.csv")89# 3. Use session state for persistence10if 'initialized' not in st.session_state:11 st.session_state.initialized = True1213# 4. Organize with containers14with st.container():15 st.header("Section 1")1617# 5. Use forms for multiple inputs18with st.form("my_form"):19 name = st.text_input("Name")20 age = st.number_input("Age")21 submitted = st.form_submit_button("Submit")2223# 6. Progress bars for long operations24with st.spinner("Loading..."):25 time.sleep(2)2627progress = st.progress(0)28for i in range(100):29 progress.progress(i + 1)Tổng Kết
Trong bài này, bạn đã học:
- ✅ Streamlit basics và cài đặt
- ✅ Input widgets: text, select, slider, button
- ✅ Display data: tables, charts
- ✅ Layout: columns, tabs, sidebar
- ✅ State management và caching
- ✅ Build complete dashboard
- ✅ Deploy to Streamlit Cloud
Bài tiếp theo: Exploratory Data Analysis (EDA)!
