Explorando dados abertos da ALMG

Autor

Rodrigo Fileto

Data de Modificação

7 de julho de 2025

Seja bem-vindo! Nesta página, exploro a plataforma de dados abertos da Assembleia Legislativa de Minas Gerais (ALMG) que oferece conjuntos de dados estruturados em diversos formatos (CSV, XML, JSON) sobre as atividades legislativas da casa. Esses dados podem ser baixados e analisados, permitindo uma compreensão mais ampla da política no Estado de Minas Gerais.

Considero essa plataforma um recurso valioso para cientistas sociais, especialmente cientistas políticos. Também pode ser de grande interesse para profissionais e entusiastas de ciência de dados.

1 Importação dos dados das proposições legislativas

Há duas formas principais para acessar os dados da ALMG. A primeira, mais simples, é o dowload direto dos arquivos csv estando atualmente disponíveis sete conjuntos: Legislação mineira, Proposições, Tramitação de proposições, Deputados da atual legislatura, Deputados desde a 8ª Legislatura e Verbas indenizatórias.

A segunda forma é por meio da API, que permite consultas mais personalizadas, com resultados no formato XML ou JSON. Para este projeto de análse exploratória, utilizei arquivos csv e dados obtidos via API em formato JSON. Por exemplo, os dados de proposições foram baixados como CSV, enquanto, enquanto dados sobre legislaturas1 foram extraídos por meio da API. Todos os arquivos foram armazenados em um banco de dados SQLite para posterior análise.

Código para importar dados de proposições
import requests
import sqlite3
import csv
from io import StringIO

def baixar_arquivo_em_memoria(ano):
    print(f"Baixando arquivos de proposições para o ano de {ano}")
    url = f"https://dadosabertos.almg.gov.br/arquivo/proposicoes/download?ano={ano}&tipo=CSV"
    response = requests.get(url)
    response.raise_for_status()
    print(f"Arquivo de {ano} baixado com sucesso na memória")
    return response.text

def criar_tabela_proposicoes(conn):
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS proposicoes (
            Codigo TEXT PRIMARY KEY,
            TipoProposicao TEXT,
            SiglaTipoProposicao TEXT,
            Numero TEXT,
            Ano TEXT,
            Ementa TEXT,
            Indexacao TEXT,
            Situacao TEXT,
            DataPublicacao TEXT,
            DataAtualizacao TEXT,
            DataUltimaAcao TEXT,
            Regime TEXT,
            Resumo TEXT,
            Origem TEXT,
            Local TEXT,
            NomeFaseAtual TEXT,
            Legislatura TEXT,
            Autores TEXT,
            LinkTextos TEXT,
            ano_arquivo INTEGER
        )
    ''')
    conn.commit()

def carregar_csv_no_sqlite(ano, conn):
    csv_text = baixar_arquivo_em_memoria(ano)
    csv_file = StringIO(csv_text)
    reader = csv.DictReader(csv_file, delimiter=',')

    cursor = conn.cursor()

    for row in reader:
        # Adiciona o ano na linha
        row['ano_arquivo'] = ano

        # Cria uma tupla com os valores na ordem correta
        values = (
            row.get('Codigo'),
            row.get('TipoProposicao'),
            row.get('SiglaTipoProposicao'),
            row.get('Numero'),
            row.get('Ano'),
            row.get('Ementa'),
            row.get('Indexacao'),
            row.get('Situacao'),
            row.get('DataPublicacao'),
            row.get('DataAtualizacao'),
            row.get('DataUltimaAcao'),
            row.get('Regime'),
            row.get('Resumo'),
            row.get('Origem'),
            row.get('Local'),
            row.get('NomeFaseAtual'),
            row.get('Legislatura'),
            row.get('Autores'),
            row.get('LinkTextos'),
            row.get('ano_arquivo')
        )

        # Executa o insert ou replace
        cursor.execute('''
            INSERT OR REPLACE INTO proposicoes (
                Codigo, TipoProposicao, SiglaTipoProposicao, Numero, Ano,
                Ementa, Indexacao, Situacao, DataPublicacao, DataAtualizacao,
                DataUltimaAcao, Regime, Resumo, Origem, Local, NomeFaseAtual,
                Legislatura, Autores, LinkTextos, ano_arquivo
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ''', values)

    conn.commit()
    print(f"Dados do ano {ano} adicionados/atualizados na tabela 'proposicoes'")

# Conectar ao banco SQLite
conn = sqlite3.connect('database.db')

# Criar tabela (se não existir)
criar_tabela_proposicoes(conn)

# Carregar dados de anos específicos
anos = range(1980, 2026)
for ano in anos:
    carregar_csv_no_sqlite(ano, conn)

# Fechar conexão
conn.close()
Código para importar dados de legislaturas
import requests
import sqlite3

# URL do JSON
url = "https://dadosabertos.almg.gov.br/api/v2/legislaturas/lista?formato=json"

# Baixar o JSON
response = requests.get(url)
data = response.json()

# Conectar ao banco SQLite (cria se não existir)
conn = sqlite3.connect('database.db')
cursor = conn.cursor()

# Criar tabela legislaturas
cursor.execute('''
CREATE TABLE IF NOT EXISTS legislaturas (
    id INTEGER PRIMARY KEY,
    dataInicio TEXT,
    dataTermino TEXT,
    dataEleicao TEXT
)
''')

# Inserir dados na tabela
for item in data.get('listaLegislatura', []):
    cursor.execute('''
    INSERT OR REPLACE INTO legislaturas (id, dataInicio, dataTermino, dataEleicao)
    VALUES (?, ?, ?, ?)
    ''', (
        item.get('id'),
        item.get('dataInicio'),
        item.get('dataTermino'),
        item.get('dataEleicao')  # Pode ser None se não existir
    ))

# Salvar (commit) e fechar conexão
conn.commit()
conn.close()

print("Dados inseridos com sucesso na tabela legislaturas.")

2 Exploração dos dados

Código
# Importações
import pandas as pd
import sys
import os
import sqlite3
import locale

# Configurações
locale.setlocale(locale.LC_ALL, 'pt_BR.UTF-8')

# Adiciona a raiz do projeto ao sys.path
sys.path.append(os.path.abspath(os.path.join(os.getcwd(), '..')))

# Importações locais
from funcoes.utils import formatar_numero_brl
from funcoes.Figuras import create_horizontal_bar_chart_go

# Configuração do banco de dados
db_path = os.path.abspath(os.path.join(os.getcwd(), '../database.db'))

# Conexão e consultas
conn = sqlite3.connect(db_path)

# Carrega dados das proposições
df = pd.read_sql_query(
    "SELECT * FROM proposicoes", 
    conn
).sort_values('Ano', ascending=False, ignore_index=True)

# Carrega dados das legislaturas
legislaturas = pd.read_sql_query("SELECT * FROM legislaturas", conn)

# Fecha conexão
conn.close()

# Processamento dos dados
nr_proposicoes = formatar_numero_brl(len(df), casas_decimais=0)

legislaturas['dataInicio'] = pd.to_datetime(
    legislaturas['dataInicio'], 
    format='%Y-%m-%d'
)

inicio_legislaturas_ano = legislaturas['dataInicio'].dt.year

A análise exploratória começa pelas proposições2. Os dados abrangem o período de 1959-2025, totalizando 193.396 registros. A Tabela 1 apresenta uma amostra destes dados. Entre as informações básicas estão o tipo, número e ano da proposição, o resumo (Ementa), temas (Indexacao) e a fase atual do processo legislativo.

Na tabela de proposições destaco ainda a coluna “Autores”, que contém um dicionário com a identificação dos parlamentares ou entidades participaram da autoria da proposição. Esta informação é útil para estudos de redes de co-autoria, permitindo identificar conexões políticas, sociais e possíveis hierarquias entre os parlamentares.

Alémd disso, a tabela oferece ainda link para download dos textos completos das proposição. Esses arquivos possibilitam análises qualitativas, como a análise do discurso, e quantitativas por meio da mineração de texto. Isso permite identificar o perfil ideológico dos parlamentares, individualmente ou em grupos, e revelar os principais temas debatidos na Casa Legislativa.

2.1 Contagem de proposições por tipo

Tabela 1: Amostra dos dados sobre proposições legislativas
Codigo TipoProposicao SiglaTipoProposicao Numero Ano Ementa Indexacao Situacao DataPublicacao DataAtualizacao DataUltimaAcao Regime Resumo Origem Local NomeFaseAtual Legislatura Autores LinkTextos ano_arquivo
0 RQC 14832/2025 REQUERIMENTO DE COMISSÃO RQC 14832 2025 Aprovado 25/06/2025 25/06/2025 18/06/2025 Votado nas comissões Comissão de Segurança Pública 20 [{"id":28864,"nome":"Deputado Delegado Christi... https://dadosabertos.almg.gov.br/api/proposico... 2025
1 RQN 10650/2025 REQUERIMENTO NUMERADO RQN 10650 2025 Aprovado 03/04/2025 11/04/2025 09/04/2025 Votado nas comissões Arquivo 20 https://dadosabertos.almg.gov.br/api/proposico... 2025
2 RQN 10619/2025 REQUERIMENTO NUMERADO RQN 10619 2025 Aprovado 03/04/2025 11/04/2025 09/04/2025 Votado nas comissões Arquivo 20 https://dadosabertos.almg.gov.br/api/proposico... 2025
3 RQN 10623/2025 REQUERIMENTO NUMERADO RQN 10623 2025 Aprovado 03/04/2025 09/04/2025 08/04/2025 Votado nas comissões Secretaria-Geral da Mesa 20 https://dadosabertos.almg.gov.br/api/proposico... 2025
4 RQN 10637/2025 REQUERIMENTO NUMERADO RQN 10637 2025 /Destinatários/Povos e Comunidades Tradicionai... Aprovado 03/04/2025 15/05/2025 13/05/2025 Votado nas comissões Arquivo 20 https://dadosabertos.almg.gov.br/api/proposico... 2025

Para finalizar essa parte introdutória na Figura 1 uma contagem dos tipos de proposição. Importante destacar que, embora os projetos de lei tenham grande representatividade, respondendo com 46.838 (cerca de 24,22), eles são superados pelos Requerimentos Numerados, que representam o tipo de proposição mais recorrente, com 75.498 (cerca de 24,22% do total).

Essa informação é relevante, considerando que a literatura frequentemente foca os projetos de lei como principal objeto de análise. É o caso por exemplo, de Fowler (2006) em que a rede de coautoria é construída com base nos projetos de lei, a fim de gerar indicadores de influência legislativa. Considero que, embora a proposição de projetos de lei seja um importante indicativo da atuação parlamentar e de seu perfil ideológico, não se deve negligenciar os demais tipos de proposição pois estes podem apresentar outras perspectivas da atividade legislativa.

Figura 1: Contagem de proposições por tipo

2.2 Evolução temporal do protocolo de proposições

Vamos observar agora a evolução das proposições legislativas ao longo do tempo. Haveria algum período específico em que os deputados e deputadas apresentam maior propensão a protocolar projetos de lei ou outros requerimentos? Para responder a essa pergunta, analisei os dados com base na data de protocolo das proposições legislativas. Não apliquei filtros quanto ao tipo de proposição nem quanto ao período, visando a uma visualização ampla e geral.

A contagem foi agrupada mensalmente com a contagem bruta e média móvel de 03 meses estão na Figura 2. Também inseri linhas verticais pontilhadas indicando o início de cada legislatura.

Destaco como principal ponto o pico de proposições no primeiro ano de cada legislatura, um fenômeno que se torna visualmente mais evidente a partir de 1987. Isso revela uma interessante avenida de pesquisa: por meio de métodos quantitativos, seria possível realizar análises estatísticas de séries temporais para identificar picos e sazonalidades de forma mais robusta, além de investigar possíveis causas para essas variações. Alternativamente, abordagens qualitativas poderiam explorar através da análise as razões para o aumento de proposições no primeiro ano de mandato.

Figura 2: Número de proposições mensais

Referências

Fowler, James H. 2006. «Connecting the Congress: A Study of Cosponsorship Networks». Political Analysis 14 (4): 456–87. https://doi.org/10.1093/pan/mpl002.

Notas de rodapé

  1. Incluem nesse conjunto a data de início, data de fim e data da eleição referente à cada legislatura.↩︎

  2. Uma “proposição” refere-se a qualquer matéria que está em tramitação na ALMG. Inclui diversos tipos de documentos como projetos de lei, projetos de lei complementar, propostas de emenda à constituição, projetos de resolução, vetos, indicações e requerimentos.↩︎