Dashboards Interativos com Streamlit
Crie dashboards interativos com Python e Streamlit. Aprenda graficos, filtros, cache, layout e deploy de aplicacoes de dados.
Streamlit transformou a forma como desenvolvedores Python criam aplicacoes de dados. Em vez de aprender HTML, CSS e JavaScript, voce escreve apenas Python e o Streamlit gera uma interface web interativa automaticamente. Neste artigo, vamos construir dashboards profissionais do zero, cobrindo graficos, filtros, cache e deploy.
Instalacao e Primeiro Dashboard
Instale o Streamlit e crie seu primeiro app:
pip install streamlit pandas plotly
Crie um arquivo app.py:
import streamlit as st
import pandas as pd
st.set_page_config(page_title="Dashboard de Vendas", layout="wide")
st.title("Dashboard de Vendas")
st.markdown("Analise completa das vendas da empresa")
# Dados de exemplo
dados = pd.DataFrame({
"Mes": ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun",
"Jul", "Ago", "Set", "Out", "Nov", "Dez"],
"Vendas": [45000, 52000, 48000, 55000, 61000, 58000,
63000, 67000, 59000, 71000, 75000, 82000],
"Meta": [50000, 50000, 50000, 55000, 55000, 55000,
60000, 60000, 60000, 70000, 70000, 70000],
"Clientes": [120, 135, 128, 142, 156, 149,
163, 171, 155, 180, 192, 205],
})
# Metricas no topo
col1, col2, col3, col4 = st.columns(4)
col1.metric("Vendas Totais", f"R$ {dados['Vendas'].sum():,.0f}")
col2.metric("Media Mensal", f"R$ {dados['Vendas'].mean():,.0f}")
col3.metric("Melhor Mes", f"R$ {dados['Vendas'].max():,.0f}")
col4.metric("Total Clientes", f"{dados['Clientes'].sum():,}")
st.dataframe(dados, use_container_width=True)
Execute com:
streamlit run app.py
Graficos Interativos com Plotly
O Streamlit integra nativamente com Plotly para graficos ricos:
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
def criar_grafico_vendas(dados: pd.DataFrame):
"""Grafico de linhas comparando vendas vs meta."""
fig = go.Figure()
fig.add_trace(go.Scatter(
x=dados["Mes"], y=dados["Vendas"],
mode="lines+markers", name="Vendas",
line=dict(color="#2E86AB", width=3),
))
fig.add_trace(go.Scatter(
x=dados["Mes"], y=dados["Meta"],
mode="lines", name="Meta",
line=dict(color="#E8443A", width=2, dash="dash"),
))
fig.update_layout(
title="Vendas vs Meta Mensal",
xaxis_title="Mes",
yaxis_title="Valor (R$)",
height=400,
)
return fig
def criar_grafico_barras(dados: pd.DataFrame):
"""Grafico de barras com cores condicionais."""
cores = ["#2E86AB" if v >= m else "#E8443A"
for v, m in zip(dados["Vendas"], dados["Meta"])]
fig = px.bar(
dados, x="Mes", y="Vendas",
title="Vendas Mensais (verde = meta batida)",
color_discrete_sequence=cores,
)
fig.update_layout(height=400)
return fig
# No app principal
st.plotly_chart(criar_grafico_vendas(dados), use_container_width=True)
col_esq, col_dir = st.columns(2)
with col_esq:
st.plotly_chart(criar_grafico_barras(dados), use_container_width=True)
with col_dir:
fig_pizza = px.pie(dados, values="Vendas", names="Mes", title="Distribuicao por Mes")
st.plotly_chart(fig_pizza, use_container_width=True)
Filtros e Interatividade
Adicione filtros para que o usuario explore os dados:
import streamlit as st
import pandas as pd
def dashboard_com_filtros():
st.sidebar.header("Filtros")
# Dados completos
df = carregar_dados()
# Filtro de periodo
meses = st.sidebar.multiselect(
"Selecione os meses",
options=df["Mes"].unique(),
default=df["Mes"].unique(),
)
# Filtro de valor minimo
valor_min = st.sidebar.slider(
"Vendas minimas (R$)",
min_value=0,
max_value=100000,
value=0,
step=5000,
)
# Filtro de regiao
regioes = st.sidebar.selectbox(
"Regiao",
["Todas", "Sudeste", "Sul", "Nordeste", "Norte", "Centro-Oeste"],
)
# Aplicar filtros
df_filtrado = df[df["Mes"].isin(meses)]
df_filtrado = df_filtrado[df_filtrado["Vendas"] >= valor_min]
if regioes != "Todas":
df_filtrado = df_filtrado[df_filtrado["Regiao"] == regioes]
# Mostrar resultados filtrados
st.subheader(f"Resultados: {len(df_filtrado)} registros")
st.dataframe(df_filtrado, use_container_width=True)
# Metricas do filtro
if not df_filtrado.empty:
col1, col2 = st.columns(2)
col1.metric("Total Filtrado", f"R$ {df_filtrado['Vendas'].sum():,.0f}")
col2.metric("Media Filtrada", f"R$ {df_filtrado['Vendas'].mean():,.0f}")
Cache para Performance
O Streamlit reexecuta o script a cada interacao. Use cache para evitar reprocessamento:
import streamlit as st
import pandas as pd
import time
@st.cache_data(ttl=3600) # Cache por 1 hora
def carregar_dados_csv(caminho: str) -> pd.DataFrame:
"""Carrega dados com cache automatico."""
df = pd.read_csv(caminho)
# Processamento pesado
df["data"] = pd.to_datetime(df["data"])
df["mes"] = df["data"].dt.month
df["ano"] = df["data"].dt.year
return df
@st.cache_resource # Cache permanente para recursos
def conectar_banco():
"""Conexao com banco de dados (reutilizada entre sessoes)."""
import sqlalchemy
engine = sqlalchemy.create_engine("postgresql://user:pass@localhost/db")
return engine
@st.cache_data
def calcular_metricas(df: pd.DataFrame) -> dict:
"""Calcula metricas agregadas."""
return {
"total_vendas": df["valor"].sum(),
"ticket_medio": df["valor"].mean(),
"total_clientes": df["cliente_id"].nunique(),
"crescimento": (
df[df["ano"] == 2025]["valor"].sum()
/ df[df["ano"] == 2024]["valor"].sum() - 1
) * 100,
}
# Uso
df = carregar_dados_csv("vendas.csv")
metricas = calcular_metricas(df)
st.metric("Total de Vendas", f"R$ {metricas['total_vendas']:,.0f}")
st.metric("Ticket Medio", f"R$ {metricas['ticket_medio']:,.0f}")
Layout Avancado com Multiplas Paginas
Organize dashboards complexos em paginas:
import streamlit as st
# Configuracao da pagina
st.set_page_config(page_title="Analytics", layout="wide")
# Navegacao
pagina = st.sidebar.radio("Navegacao", ["Visao Geral", "Vendas", "Clientes", "Produtos"])
if pagina == "Visao Geral":
st.header("Visao Geral")
col1, col2, col3 = st.columns(3)
col1.metric("Receita", "R$ 756.000", "+12%")
col2.metric("Clientes Ativos", "1.842", "+8%")
col3.metric("NPS", "72", "+5")
# Tabs dentro da pagina
tab1, tab2 = st.tabs(["Mensal", "Trimestral"])
with tab1:
st.write("Dados mensais aqui")
with tab2:
st.write("Dados trimestrais aqui")
elif pagina == "Vendas":
st.header("Analise de Vendas")
# Upload de arquivo
arquivo = st.file_uploader("Carregar dados de vendas", type=["csv", "xlsx"])
if arquivo is not None:
if arquivo.name.endswith(".csv"):
df = pd.read_csv(arquivo)
else:
df = pd.read_excel(arquivo)
st.dataframe(df)
elif pagina == "Clientes":
st.header("Analise de Clientes")
st.info("Selecione um cliente para ver o historico")
elif pagina == "Produtos":
st.header("Catalogo de Produtos")
st.warning("Dados sendo atualizados")
Formularios e Entrada de Dados
O Streamlit tambem serve para criar formularios de entrada:
import streamlit as st
def formulario_cadastro():
st.subheader("Cadastro de Produto")
with st.form("form_produto"):
nome = st.text_input("Nome do Produto")
categoria = st.selectbox("Categoria", ["Eletronicos", "Roupas", "Alimentos"])
preco = st.number_input("Preco (R$)", min_value=0.0, step=0.01)
estoque = st.number_input("Estoque", min_value=0, step=1)
descricao = st.text_area("Descricao")
destaque = st.checkbox("Produto em destaque")
enviado = st.form_submit_button("Cadastrar")
if enviado:
if nome and preco > 0:
st.success(f"Produto '{nome}' cadastrado com sucesso!")
st.json({
"nome": nome,
"categoria": categoria,
"preco": preco,
"estoque": estoque,
"destaque": destaque,
})
else:
st.error("Preencha todos os campos obrigatorios.")
Deploy do Dashboard
Para disponibilizar seu dashboard, o Streamlit Community Cloud e a opcao mais simples:
# requirements.txt
streamlit==1.32.0
pandas==2.2.0
plotly==5.18.0
Basta conectar seu repositorio GitHub ao Streamlit Cloud e o deploy e automatico. Para ambientes corporativos, use Docker:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8501
CMD ["streamlit", "run", "app.py", "--server.port=8501"]
Boas Praticas
Mantenha o processamento pesado fora do fluxo principal usando cache. Organize o codigo em funcoes reutilizaveis. Use st.spinner() para indicar carregamento em operacoes lentas. Teste o dashboard com diferentes tamanhos de tela, ja que o Streamlit e responsivo por padrao. E sempre valide entradas do usuario antes de processar dados.
Conclusao
Streamlit democratiza a criacao de dashboards em Python. Sem necessidade de conhecer frontend, voce constroi aplicacoes de dados interativas e visualmente atrativas. Com cache, filtros e integracao com Plotly, e possivel criar dashboards que atendem desde analises exploratórias ate paineis de producao. Comece com um dashboard simples e evolua conforme as necessidades do seu projeto.
Equipe Python Brasil
Contribuidor do Python Brasil — Aprenda Python em Português