Spaces:
Runtime error
Runtime error
| import pandas as pd | |
| import plotly.express as px | |
| import plotly.graph_objects as go | |
| import streamlit as st | |
| # --- 1. Configuração da Página --- | |
| st.set_page_config(layout="wide") | |
| st.title(f"Análise de Desempenho Eleitoral (1998, 2006, 2010)") | |
| st.header("Candidata: Nilmar Gavino Ruiz") | |
| # --- 2. Função de Carregamento e Processamento dos Dados --- | |
| def carregar_dados(): | |
| try: | |
| # --- Processar 1998 --- | |
| file_1998 = "votacao_candidato-municipio_deputado_federal_1998_to_270002706025551.csv" | |
| df_1998 = pd.read_csv(file_1998, sep=';', encoding='latin-1', on_bad_lines='skip') | |
| df_1998['Percentual'] = (df_1998['qt_votos_nom_validos'] / df_1998['qt_votos_concorrentes']) * 100 | |
| df_perc_1998 = df_1998[['nm_municipio', 'Percentual']].rename(columns={ | |
| 'nm_municipio': 'Municipio', | |
| 'Percentual': 'Perc_1998' | |
| }) | |
| total_1998 = int(df_1998['qt_votos_nom_validos'].sum()) | |
| # --- Processar 2006 --- | |
| file_2006 = "votacao_candidato-municipio_deputado_federal_2006_to_10272.csv" | |
| df_2006 = pd.read_csv(file_2006, sep=';', encoding='latin-1', on_bad_lines='skip') | |
| df_2006['Percentual'] = df_2006['pc_votos_validos'].str.replace(',', '.').astype(float) * 100 | |
| df_perc_2006 = df_2006[['nm_municipio', 'Percentual']].rename(columns={ | |
| 'nm_municipio': 'Municipio', | |
| 'Percentual': 'Perc_2006' | |
| }) | |
| total_2006 = int(df_2006['qt_votos_nom_validos'].sum()) | |
| # --- Processar 2010 --- | |
| file_2010 = "votacao_candidato-municipio_deputado_federal_2010_to_270000000260.csv" | |
| df_2010 = pd.read_csv(file_2010, sep=';', encoding='latin-1', on_bad_lines='skip') | |
| df_2010['Percentual'] = df_2010['pc_votos_validos'].str.replace(',', '.').astype(float) * 100 | |
| df_perc_2010 = df_2010[['nm_municipio', 'Percentual']].rename(columns={ | |
| 'nm_municipio': 'Municipio', | |
| 'Percentual': 'Perc_2010' | |
| }) | |
| total_2010 = int(df_2010['qt_votos_nom_validos'].sum()) | |
| # --- Juntar (Merge) as tabelas de porcentagem --- | |
| df_merged = pd.merge(df_perc_1998, df_perc_2006, on='Municipio', how='outer') | |
| df_final_perc = pd.merge(df_merged, df_perc_2010, on='Municipio', how='outer') | |
| df_final_perc = df_final_perc.fillna(0) | |
| df_final_perc['Cresc_Perc_98_10'] = df_final_perc['Perc_2010'] - df_final_perc['Perc_1998'] | |
| df_total = pd.DataFrame({ | |
| 'Ano': ['1998', '2006', '2010'], | |
| 'Total de Votos': [total_1998, total_2006, total_2010] | |
| }) | |
| return df_final_perc.round(2), df_total | |
| except FileNotFoundError as e: | |
| st.error(f"ERRO: Arquivo CSV não encontrado! {e.filename}") | |
| st.stop() | |
| # Carrega os dados | |
| df_perc, df_total = carregar_dados() | |
| # --- 3. Construção do Dashboard --- | |
| st.subheader("Evolução da Votação Total (Votos Absolutos)") | |
| fig_total = px.line(df_total, x='Ano', y='Total de Votos', title='Evolução da Votação Total (1998-2010)', markers=True) | |
| st.plotly_chart(fig_total, use_container_width=True) | |
| st.subheader("Análise Estratégica de Penetração (%)") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| # --- O "Funil de Batalha" (Tier List) --- | |
| def classificar_tier(penetracao): | |
| if penetracao >= 10: return 'S (Reduto)' | |
| elif 5 <= penetracao < 10: return 'A (Forte)' | |
| elif 1 <= penetracao < 5: return 'B (Batalha)' | |
| else: return 'C (Fraco)' | |
| df_perc['Tier_2010'] = df_perc['Perc_2010'].apply(classificar_tier) | |
| resumo_tier = df_perc['Tier_2010'].value_counts().sort_index() | |
| fig_tier = px.pie( | |
| resumo_tier, | |
| values=resumo_tier.values, | |
| names=resumo_tier.index, | |
| title='Proporção de Municípios por "Tier" (Base 2010)' | |
| ) | |
| fig_tier.update_traces(textposition='inside', textinfo='percent+label+value') | |
| st.plotly_chart(fig_tier, use_container_width=True) | |
| with col2: | |
| # --- Gráfico dos Principais Redutos (por %) --- | |
| df_top20_perc_2010 = df_perc.sort_values(by='Perc_2010', ascending=False).head(20) | |
| df_top20_melted = df_top20_perc_2010.melt( | |
| id_vars='Municipio', | |
| value_vars=['Perc_1998', 'Perc_2006', 'Perc_2010'], | |
| var_name='Ano', | |
| value_name='Penetração (%)' | |
| ) | |
| fig_perc = px.bar( | |
| df_top20_melted, | |
| x='Penetração (%)', y='Municipio', | |
| color='Ano', barmode='group', | |
| title='Comparativo dos 20 Maiores "Redutos" (por % de votos em 2010)', | |
| orientation='h' | |
| ) | |
| fig_perc.update_layout(yaxis={'categoryorder':'total descending'}, height=600) | |
| st.plotly_chart(fig_perc, use_container_width=True) | |
| st.subheader("Tabelas de Análise (Crescimento e Queda)") | |
| col_cresc, col_queda = st.columns(2) | |
| with col_cresc: | |
| st.markdown("##### Top 10 'Crescimento de Força' (Maior Ganho % de 98 a 10)") | |
| df_crescimento = df_perc.sort_values(by='Cresc_Perc_98_10', ascending=False).head(10)[['Municipio', 'Perc_1998', 'Perc_2010', 'Cresc_Perc_98_10']] | |
| st.dataframe(df_crescimento) | |
| with col_queda: | |
| st.markdown("##### Top 10 'Perda de Força' (Maior Queda % de 98 a 10)") | |
| df_queda = df_perc.sort_values(by='Cresc_Perc_98_10', ascending=True).head(10)[['Municipio', 'Perc_1998', 'Perc_2010', 'Cresc_Perc_98_10']] | |
| st.dataframe(df_queda) | |
| with st.expander("Ver a Super-Tabela Completa de Penetração (%)"): | |
| st.dataframe(df_perc.sort_values(by='Perc_2010', ascending=False)) |