Criação de Painéis - Consumidor de Perguntas
Objetivos
O objetivo deste tutorial é criar um consumidor básico para a plataforma GeoProcess. A ideia é criar um consumidor didático com dados do IBGE.
Índice
- O que é um consumer?
- O que podemos fazer em um consumer?
- Executando o consumer basic
- Criando um consumidor do IBGE
O que é um consumer?
Um consumer de perguntas é um módulo que fornece respostas para perguntas feitas pelo usuário na plataforma do geoprocess. O módulo é capaz de exibir dados em formas de gráficos e tabelas e auxilia o usuário a descobrir tendências e anomalias, o que por conseguinte, favorece a adoção de medidas preventivas e corretivas. Neste tutorial, iremos utilizar o módulo consumer basic, uma estrutura básica pronta para auxiliar no processo de construção de consumidores. Ele oferece um modelo simples e adaptável, projetado para ser copiado e ajustado conforme as necessidades específicas do usuário na plataforma GeoProcess.
O que podemos fazer em um consumer?
O consumer utiliza a biblioteca Plotly, ela é uma biblioteca que possui diversos tipos de gráficos para exibir diferentes dados, de diferentes formas, para maior eficiência, aqui vão algumas demonstrações do que se pode criar com um consumer:
Gráficos de linha:

Mapas Cloropléticos:

Histogramas:

Gráficos de Bolhas:

Mais gráficos estão disponíveis para visualização no link:
https://chart-studio.plotly.com/
Executando o consumer basic
Atenção: Para que que a aplicação funcione, todos arquivos devem estar na pasta geoprocess, criada no primeiro tutorial!
Primeiramente, copie o projeto pgst-consumer-basic para um novo projeto chamado consumer-ibge, utilizando o comando abaixo:
Abra um terminal na pasta consumer-ibge, copie o arquivo de configuração do ambiente:
Abra o arquivo env.conf e atualize o nome do consumidor (propriedade CONSUMER_CODE) para o nome tutorial1.
Instale o ambiente virtual para isolar as dependências do Python. Utilize o comando abaixo:
Ative o ambiente virtual no seu computador utilizando o comando abaixo:
Instale as dependências do projeto.
Instale as dependências do projeto pgst-lib dentro do projeto consumidor.
Para executar a aplicação, utilize a linha de comando abaixo:
Usando esse modo a resposta pode ser acessada depois de rodar teste de contrato no arquivo answer.json na pasta answer.
Abra o resultado da aplicação através da URL: http://127.0.0.1:8000/.
A seguinte tela deverá ser exibida:

Criando um consumidor do IBGE
O objetivo deste consumidor é mostrar o pontencial da ferramenta GeoProcess. Para isso, um consumidor de exemplo com dados do IBGE será criado. Esse consumidor utiliza dados do IBGE dos estados brasileiros, com informações do PIB, IDH e População. A ideia é que esse consumidor receba um parâmetro como entrada que representa o total de estados avaliados nas respostas dos gráficos. Como resposta fornecida teremos alguns gráficos e tabelas com os estados com maiores populações, maiores PIB e maiores IDH.
Configuração inicial
Na primeira etapa, iremos definir as perguntas as quais o consumer irá responder, desta forma, acesse o arquivo questions.json e substitua o código pelo seguinte conteúdo:
{
"projects": [
{
"consumer_project_id": "TUTORIAL",
"version": "1.0.0",
"title": "Projetos Tutoriais",
"role_tag": "TUTORIAL"
}
],
"themes": [
{
"consumer_theme_id": "TT1",
"version": "1.0.0",
"title": "Tema Único",
"role_tag": "TT1",
"consumer_project_id": "TUTORIAL"
}
],
"questions": [
{
"consumer_question_id": "Q1",
"version": "1.0.0",
"consumer_theme_id": "TT1",
"title": "Análise dos estados do Brasil",
"description": "Quais os estados com as N maiores populações, PIB, IDH do Brasil?",
"role_tag": "QT1",
"consumer_sources": [
"Dados Artificiais"
],
"config_items": [
{
"id": "valorN",
"label": "Selecione o valor de N",
"type": "range",
"step": 1,
"min": 1,
"max": 27,
"required": true
}
]
}
]
}
Na seção questions são definidas as perguntas, cada pergunta possui uma ID, descrição e versão, em config_items definimos o parâmetro a ser solicitado ao usuário, o parâmetro nesse caso é do tipo range, assim deve ser selecionado um valor que esteja entre a faixa de mine max, requiredtorna o parâmetro obrigatório, e step determina de quanto em quanto o valor deve ser incrementado ao escolher. Neste caso, gostariamos de saber quais os estados com as maiores N populações, PIB e IDH.
Acesse o arquivo /tests/contract/001/answerRequest.json e insira o contéudo:
{
"header": {
"type": "answer_request",
"status": "OK",
"next_consumer": null
},
"content": {
"user_info": {
"user": "dev",
"name": "Developer",
"email": "dev@ufla.br",
"ip": "127.0.0.1"
},
"consumer_question_id": "Q1",
"answer_request_id": 11,
"data": {
"valorN": "7"
}
}
}
Criando Gráficos
Acesse consumer/basicworker.py e substitua todo o código pelo seguinte trecho:
import logging
import json
import pandas as pd
import datetime
from baseconsumer.worker import Worker
from baseconsumer.worker import process
from util.answer import Answer
from util.answer import ChartType
from util.answer import Color
from util.answer import Message
from util.answer import getColor
class BasicWorker(Worker):
"""Modelagem da classe BasicWorker que herda da classe Worker.
Esta classe contém o esqueleto básico de um consumidor genérico
que deve ser adaptado para um propósito específico.
"""
logger = logging.getLogger(__name__)
messages = {
"001": Message("001", "Consumidor IBGE", "Exemplo IBGE"),
}
def getVersion(self):
"""Retorna a versão do consumidor.
Returns:
(str): Versão do consumidor
"""
return "1.0"
def getName(self):
"""Retorna o nome do consumidor.
Returns:
(str): Nome do consumidor
"""
return "Consumidor IBGE"
Essa é a parte inicial da criação de um consumer, ainda não é possível visualizar, uma vez que não criamos nenhum gráfico. Dentro de BasicWorker iremos inserir os processos que retornarão gráficos para o portal, no início da classe, podemos definir uma mensagem a ser exibida ao abrir o consumer. No fim do código adicionamos a mensagem ao consumer e retornamos ela ao portal.
Antes de adicionar um gráfico, crie uma pasta data em consumer-ibge e insira o arquivo dados.csv que está disponível para download na pasta docs deste tutorial.
Agora, iremos criar um gráfico de barras que exibe as N (7) maiores populações do brasil e relacionar seus PIBs em uma escala de cores:
Abaixo da linha 40, insira o seguinte trecho:
@process(name="Answer 1", questionId="Q1")
def process1(self, answer_request):
"""Processa a primeira pergunta e gera um gráfico de barras."""
self.logger.info("Processando a primeira pergunta")
valorN = int(answer_request.getPropertie("valorN"))
answer = Answer()
path = "./data/dados.csv"
df = pd.read_csv(path)
# gráfico 1
df_sorted = df.sort_values("População", ascending=False).head(valorN)
data = {
"data": [{
"type": "bar",
"x": df_sorted["Estado"].tolist(),
"y": df_sorted["População"].tolist(),
"marker": {
"color": df_sorted["IDH"].tolist(),
"colorscale": "Viridis",
"colorbar": {"title": "IDH"},
"showscale": True
},
"hovertemplate": (
"Estado: %{x}<br>" +
"População: %{y:,}<br>" +
"IDH: %{marker.color:.3f}<extra></extra>"
)
}],
"layout": {
"title": {"text": f"Estados com as {valorN} maiores populações, com IDH"},
"xaxis": {"title": "Estado"},
"yaxis": {"title": "População"}
}
}
answer.addChartPlotly(f"Estados com as {valorN} maiores populações", data)
return answer
Antes de executar o programa, é necessário instalar a biblioteca do pandas, no terminal digite:
Em seguida, atualize o arquivo requirements.txt com a biblioteca do pandas e a versão instalada.
Execute o programa para visualizar a alteração:
Abra a aplicação através da URL: http://127.0.0.1:8000/.
Resultado esperado:

Os gráficos são gerados por meio de um dicionário que é passado para a variável data, os parâmetros passados para a variável definem o gráfico resultante. O item datadefine as propriedades do gráfico como o seu tipo, o que será exibido no eixo x e y dentre outros itens que variam conforme o tipo de gráfico. Hovertemplate define as informações que serão exibidas ao passar o cursor acima de um item. Já em layout definimos o título e o nome da informações do eixo x e y. É possível encontrar informações sobre tais parâmetros no link abaixo:
https://plotly.com/python/reference/
Agora, vamos inserir um gráfico de bolhas, de modo que possamos relacionar os três critérios que desejamos avaliar, PIB, IDH e população.
Atenção: Não esqueça de excluir return answer da linha anterior ao adicionar um novo gráfico.
Após a linha answer.addChartPlotly(f"Estados com as {valorN} maiores populações", data) insira o trecho de código:
data = {
"data": [{
"type": "scatter",
"mode": "markers",
"x": df_sorted["IDH"].tolist(),
"y": df_sorted["PIB"].tolist(),
"text": df_sorted["Estado"].tolist(), # rótulos ao passar o mouse
"marker": {
"size": df_sorted["População"].tolist(),
"sizemode": "area",
"sizeref": 2.*max(df_sorted["População"]) / (100**2), # escala automática
"sizemin": 4,
"color":df_sorted["População"].tolist(),
"colorbar": {"title": "População"},
"colorscale":"Viridis",
"showscale":True
},
"hovertemplate": (
"Estado: %{text}<br>" +
"População: %{marker.color} milhões <br>" +
"IDH: %{x:.3f}<br>"+
"PIB: %{y:.3f}<extra></extra>"
)
}],
"layout": {
"title": {"text": "Gráfico Bubble Chart"},
"xaxis": {"title": "IDH"},
"yaxis": {"title": "PIB"}
}
}
answer.addChartPlotly("Estados Ordenados por População, PIB e IDH", data)
return answer
Execute o programa para visualizar a alteração:
Abra a aplicação através da URL: http://127.0.0.1:8000/.
Resultado esperado:

Vamos inserir um gráfico cloroplético para visualizar os dados de todos estados do Brasil, o parâmetro input não será necessário neste momento, uma vez que vamos analisar todos estados do país afim de ver como os 7 maiores estados se destacam em relação ao restante do país.
Na primeira linha do código insira o trecho:
Em seguida insira o conteúdo após a linhaanswer.addChartPlotly("Estados Ordenados por População e PIB", data) (não esqueça de excluir return answer):
url = "https://raw.githubusercontent.com/codeforamerica/click_that_hood/master/public/data/brazil-states.geojson"
geojson = requests.get(url).json()
customdata = df[["IDH", "PIB", "População"]].values.tolist()
data = {
"data": [
{
"type": "choropleth",
"z": df["População"].tolist(),
"text": df["Estado"].tolist(),
"colorscale": "Viridis",
"colorbar": {"title": "População"},
"geojson": geojson,
"locations": df["Estado"].tolist(),
"featureidkey": "properties.name",
"showscale": True,
"reversescale": False,
"customdata": customdata,
"hovertemplate": (
"<b>%{location}</b><br>" +
"População: %{z:,} Milhões <br>" +
"PIB: %{customdata[1]:,.2f}<br>" +
"IDH: %{customdata[0]:.3f}<extra></extra>"
)
}
],
"layout": {
"geo": {
"scope": "south america", # foca no Brasil e América do Sul
"showframe": False,
"projection": {"type": "mercator"},
"showcoastlines": False
},
"title": "Mapa Coroplético - Estados do Brasil e seus dados",
"autosize": True,
"margin": {"l":0,"r":0,"t":50,"b":0} # remove espaços em branco
},
"frames": [],
"config": {
"responsive": True # permite que ocupe todo o contêiner
}
}
answer.addChartPlotly("Dados de todos estados do Brasil com escala de cores baseada no tamanho da População.",data)
return answer
Execute o programa para visualizar a alteração:
Abra a aplicação através da URL: http://127.0.0.1:8000/.
Resultado esperado:

Em nosso consumer, também é possível inserir tabelas, nesse passo vamos inserir uma tabela que exibe todos os dados de todos estados.
Exclua o return answer do gráfico anterior e insira o contéudo após a linha answer.addChartPlotly("Dados de todos estados do Brasil com escala de cores baseada no tamanho da População.",data):
#Tabela1
dadosTabela = df[["Estado", "População", "IDH", "PIB"]].values.tolist()
answer.addTable("Tabela com informações da base de dados do IBGE",
"Dados do IBGE",
["Estado", "População" + " (milhões)", "IDH", "PIB" + " (US$ bilhões)"],
dadosTabela)
return answer
Execute o programa para visualizar a alteração:
Abra a aplicação através da URL: http://127.0.0.1:8000/.
Resultado esperado:

Answer possui um método especial para criação de tabelas, como parâmetros são passados os seguintes valores: Título da tabela, nome dos dados, uma lista com o nome de cada coluna e uma fonte de dados.
Por fim, antes de return answer, insira o seguinte código:
answer.addMessage(self.messages["001"]) adiciona ao consumer a mensagem que definimos no início do consumer, em Class BasicWorker.
Execute o programa para visualizar a alteração:
Abra a aplicação através da URL: http://127.0.0.1:8000/.
Resultado esperado:

Para executar em produção entre no terminal e digite:
Atenção: O docker deve estar em execução para executar em produção!
Acesse a URL http://0.0.0.0:8000/.
Resultado Esperado:

Resultado Final:

Pronto! Agora você já sabe como gerar gráficos, mapas e tabelas interativos para visualizar e analisar informações dos estados brasileiros. Explore outras perguntas e dados para continuar descobrindo o potencial desta poderosa ferramenta!