Guia Prático para Graduandos:
Dashboards Interativos com Dash e Plotly
Um guia completo para criar visualizações de dados dinâmicos e impactantes utilizando Python.
Objetivos da Cartilha
Esta cartilha foi desenvolvida para guiar estudantes de graduação na jornada de criação de dashboards interativos. Nossos principais objetivos são:
Introduzir Conceitos
Apresentar os conceitos fundamentais por trás da visualização de dados e a importância dos dashboards na análise de informações.
Ensinar Ferramentas
Capacitar os alunos com o conhecimento prático das bibliotecas Dash e Plotly para a construção de dashboards em Python.
Inspirar com Exemplos
Fornecer exemplos práticos e com código-fonte que sirvam como base e inspiração para projetos futuros dos estudantes.
Instalação e Configuração
Siga estes passos para configurar seu ambiente de desenvolvimento e executar seu primeiro dashboard.
1. Instale o Visual Studio Code
O VS Code é um editor de código-fonte leve, mas poderoso, que é executado em seu desktop e está disponível para Windows, macOS e Linux. Ele vem com suporte integrado para JavaScript, TypeScript e Node.js e tem um rico ecossistema de extensões para outras linguagens (como Python) e tempos de execução.
2. Instale o `uv` (Gerenciador de Pacotes)
`uv` é um instalador e resolvedor de pacotes Python extremamente rápido, escrito em Rust. Ele é projetado como um substituto para `pip` e `pip-tools`. Para instalá-lo, siga as instruções no site oficial.
3. Inicialize seu Projeto
Navegue até a pasta do seu projeto no terminal e execute o comando abaixo. Isso criará um ambiente virtual e o arquivo `pyproject.toml`, que gerencia as dependências do seu projeto.
$ uv init
4. Adicione as Dependências
Agora, instale as bibliotecas Python necessárias para o nosso projeto. Este comando adicionará `dash`, `pandas` e outras bibliotecas úteis ao seu ambiente.
$ uv add dash==3.1.1 dash-ag-grid==32.3.1 dash-iconify>=0.1.2 dash-mantine-components>=2.1.0 dash-player>=1.1.0 pandas>=2.3.1
5. Crie a Aplicação Mínima
Crie um arquivo chamado `main.py` e adicione o código a seguir. Este é um aplicativo Dash interativo para garantir que nossa configuração está funcionando e para testar o hot-reload.
from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv')
app = Dash()
app.layout = [
html.H1(children='Title of Dash App', style={'textAlign':'center'}),
dcc.Dropdown(df.country.unique(), 'Canada', id='dropdown-selection'),
dcc.Graph(id='graph-content')
]
@callback(
Output('graph-content', 'figure'),
Input('dropdown-selection', 'value')
)
def update_graph(value):
dff = df[df.country==value]
return px.line(dff, x='year', y='pop')
if __name__ == '__main__':
app.run(debug=True)
6. Execute e Teste o Hot-Reload
Execute o aplicativo. A opção `debug=True` ativa o "Hot Reload", que recarrega o servidor automaticamente sempre que você salva uma alteração no código.
$ uv run python main.py
Atenção: Se você salvar o arquivo com um erro de sintaxe, o servidor pode parar. Se isso acontecer, corrija o erro e execute o comando `uv run python main.py` novamente.
Construindo o Dashboard: Passo a Passo
Agora que o ambiente está configurado, transforme seu app mínimo em um dashboard completo para análise de dados de ecocardiogramas. Cada passo adiciona uma nova funcionalidade ao nosso projeto.
Passo 1: Baixe o Conjunto de Dados
O primeiro passo é obter os dados.
1. Acesse o Heart Disease Dataset no Kaggle.
2. Baixe e extraia o arquivo `archive.zip`.
3. Mova o `heart.csv` para a pasta do seu projeto.
# Importações necessárias para o projeto
import dash_mantine_components as dmc
from dash import Dash, Input, Output, clientside_callback, dcc
import dash_ag_grid as dag
import pandas as pd
import plotly.express as px
from dash_iconify import DashIconify
# Inicializa a aplicação Dash
app = Dash()
# Carrega os dados do ecocardiograma
dataframe = pd.read_csv("heart.csv")
# Execute o arquivo para testar se está funcionando
if __name__ == "__main__":
app.run(debug=True)
Passo 2: Imports e Leitura dos Dados
Apague o código mínimo e comece com as importações específicas. Carregue o arquivo [`heart.csv`](heart.csv:1) que você baixou. Execute para verificar se não há erros de importação.
# Adicione após carregar os dados, antes do if __name__:
# Define a estrutura básica do layout
layout = dmc.AppShell(
[
dmc.AppShellHeader(
dmc.Group(
[
dmc.Title("Dashboard Ecocardiograma", order=1, c="blue"),
],
justify="space-between",
style={"flex": 1},
h="100%",
px="md",
),
),
dmc.AppShellMain(
dmc.Text("Conteúdo será adicionado aqui", size="lg", ta="center", py="xl")
),
],
header={"height": 60},
padding="md",
)
# Aplica o layout usando MantineProvider
app.layout = dmc.MantineProvider(layout)
Passo 3: Estrutura Básica do Layout
Crie a estrutura usando [`dmc.AppShell()`](main.py:1) com cabeçalho ([`AppShellHeader`](main.py:1)) e área principal ([`AppShellMain`](main.py:1)). O [`MantineProvider`](main.py:1) fornece temas consistentes.
# Substitua o conteúdo do dmc.AppShellMain por:
dmc.AppShellMain(
dmc.Container(
dmc.Card(
children=[
dmc.CardSection(
dmc.Text("Distribuição das Idades", fw=500, size="lg"),
withBorder=True,
inheritPadding=True,
py="xs"
),
dmc.CardSection(
dcc.Graph(
figure=px.histogram(
dataframe,
x="age",
nbins=20,
title="Histograma das Idades dos Pacientes"
)
)
),
],
withBorder=True,
shadow="sm",
radius="md",
mt="md"
),
size="xl"
)
)
Passo 4: Primeiro Gráfico
Adicione seu primeiro gráfico usando [`px.histogram()`](main.py:1) dentro de um [`dmc.Card()`](main.py:1). O card possui seções para título e conteúdo, criando uma apresentação organizada.
# Substitua o dmc.AppShellMain com um grid de gráficos:
dmc.AppShellMain(
dmc.Grid(
children=[
# Gráfico 1: Distribuição das Idades
dmc.GridCol(
dmc.Card([
dmc.CardSection(dmc.Text("Distribuição das Idades", fw=500), withBorder=True, inheritPadding=True, py="xs"),
dmc.CardSection(dcc.Graph(figure=px.histogram(dataframe, x="age", nbins=20))),
], withBorder=True, shadow="sm", radius="md"),
span="auto",
),
# Gráfico 2: Distribuição por Sexo
dmc.GridCol(
dmc.Card([
dmc.CardSection(dmc.Text("Distribuição por Sexo", fw=500), withBorder=True, inheritPadding=True, py="xs"),
dmc.CardSection(dcc.Graph(figure=px.bar(
dataframe["sex"].value_counts().rename_axis("sex").reset_index(name="count"),
x="sex", y="count"
))),
], withBorder=True, shadow="sm", radius="md"),
span="auto",
),
# Gráfico 3: Scatter Plot
dmc.GridCol(
dmc.Card([
dmc.CardSection(dmc.Text("Colesterol vs. Frequência Máxima", fw=500), withBorder=True, inheritPadding=True, py="xs"),
dmc.CardSection(dcc.Graph(figure=px.scatter(dataframe, x="chol", y="thalach", color="target"))),
], withBorder=True, shadow="sm", radius="md"),
span="auto",
),
# Gráfico 4: Box Plot
dmc.GridCol(
dmc.Card([
dmc.CardSection(dmc.Text("Pressão Arterial por Classe Alvo", fw=500), withBorder=True, inheritPadding=True, py="xs"),
dmc.CardSection(dcc.Graph(figure=px.box(dataframe, x="target", y="trestbps"))),
], withBorder=True, shadow="sm", radius="md"),
span="auto",
),
],
gutter="xs",
),
)
Passo 5: Sistema de Grid com Múltiplos Gráficos
Implemente um sistema de grid usando [`dmc.Grid()`](main.py:1) e [`dmc.GridCol()`](main.py:1) para organizar quatro tipos diferentes de gráficos: histograma, barra, scatter e box plot.
# Adicione após carregar o dataframe, antes do layout:
# Cria a tabela interativa
tabela = dag.AgGrid(
rowData=dataframe.to_dict("records"),
columnDefs=[{"field": i} for i in dataframe.columns],
defaultColDef={"resizable": True, "sortable": True, "filter": True},
className="ag-theme-alpine",
)
# Depois, adicione ao final do Grid, antes de fechar o children=[]:
# Tabela de Dados - nova linha completa
dmc.GridCol(
dmc.Card([
dmc.CardSection(
dmc.Text("Tabela de Dados", fw=500),
withBorder=True,
inheritPadding=True,
py="xs"
),
dmc.CardSection(tabela),
], withBorder=True, shadow="sm", radius="md"),
span=12, # Ocupa toda a largura
),
Passo 6: Tabela de Dados Interativa
Adicione uma tabela interativa usando [`dag.AgGrid()`](main.py:1) que permite ordenação, filtro e redimensionamento de colunas. A tabela ocupa a largura total com [`span=12`](main.py:1).
# Adicione após as importações, antes de carregar o dataframe:
# Botão para alternar entre tema claro e escuro
botao_troca_tema = dmc.Switch(
offLabel=DashIconify(icon="radix-icons:sun", width=15),
onLabel=DashIconify(icon="radix-icons:moon", width=15),
id="color-scheme-switch",
persistence=True,
color="grey",
)
# Modifique o cabeçalho para incluir o botão:
dmc.AppShellHeader(
dmc.Group(
[
dmc.Title("Dashboard Ecocardiograma", order=1, c="blue"),
botao_troca_tema, # Adiciona o botão aqui
],
justify="space-between",
style={"flex": 1},
h="100%",
px="md",
),
),
Passo 7: Botão de Alternância de Tema
Adicione um [`dmc.Switch()`](main.py:1) com ícones do [`DashIconify`](main.py:1) para alternar entre temas claro e escuro. O [`persistence=True`](main.py:1) mantém a preferência do usuário.
# Adicione após definir app.layout, antes do if __name__:
# Callback para alternar o tema usando JavaScript no cliente
clientside_callback(
"""
(switchOn) => {
document.documentElement.setAttribute(
'data-mantine-color-scheme',
switchOn ? 'dark' : 'light'
);
return window.dash_clientside.no_update
}
""",
Output("color-scheme-switch", "id"),
Input("color-scheme-switch", "checked"),
)
# Adicione também um ID ao AppShell para controle de tema:
# Modifique a linha do dmc.AppShell para incluir:
# dmc.AppShell([...], header={"height": 60}, padding="md", id="appshell")
Passo 8: Callbacks e Interatividade
Implemente um [`clientside_callback()`](main.py:1) que executa JavaScript no navegador para alternar o tema instantaneamente, sem precisar comunicar com o servidor Python.
Passo 9: Dashboard Completo e Interativo
Parabéns! Você construiu um dashboard completo seguindo uma abordagem incremental. Cada passo adicionou uma funcionalidade específica, permitindo compreender como cada elemento contribui para o resultado final.
📚 Conceitos Aprendidos:
- • Importações organizadas: Como estruturar as dependências do projeto
- • Layout responsivo: Uso do AppShell e sistema de Grid
- • Componentes visuais: Cards, seções e elementos de UI
- • Visualizações de dados: Diferentes tipos de gráficos com Plotly
- • Tabelas interativas: AG-Grid com funcionalidades avançadas
- • Temas dinâmicos: Sistema de alternância claro/escuro
- • Callbacks: Interatividade client-side e server-side
Para referência, aqui está o código completo final:
{/* Código final completo será inserido aqui pelo script */}