Eleições para segundo turno em Duque de Caxias - RJ

Antes de qualquer código e gráfico, vamos a alguns conceitos que serão colocados nas análises a seguir:

As eleições para os cargos executivos (prefeito, governador e presidente) são eleições majoritárias, isto é, o candidato eleito será o que tiver mais votos. Este trabalho visa a analisar, graficamente, dados além dos votos válidos, que são os votos brancos e nulos, e abstenções.

Dois fatos chamam a atenção quando analisa-se a eleição referida:

  • A proporção de eleitores que se absteram de votar, somados os que anularam seus votos, foi considerável (mais de 30%)
  • A soma desses potenciais votos, foi maior que a soma dos votos válidos para o candidato eleito

Assim, os dados a seguir, acabam por explicitar a problemática da eleição no Brasil, a qual desconsidera os votos inválidos e abstenções na hora da apuração dos votos.

In [1]:
import pandas as pd
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode(connected=True)
from eleicoes_analysis import *

df_secao = pd.read_csv('dataset/detalhe_votacao_secao_duque_de_caxias.csv')
df_zona = pd.read_csv('dataset/detalhe_votacao_zona_duque_de_caxias.csv')
df_local_votacao = pd.read_csv('dataset/detalhe_votacao_localizacao_consolidado_duque_de_caxias.csv')

numeros_consolidados = getConsolidateNumbers(df_secao)
total_votos_validos = numeros_consolidados.get('validos')
total_votos_nao_considerados = numeros_consolidados.get('nao_considerados')
total_abstencoes = numeros_consolidados.get('abstencoes')
total_brancos = numeros_consolidados.get('brancos')
total_nulos = numeros_consolidados.get('nulos')

numeros_consolidados_por_candidato = getConsolidateNumbersByCandidate(df_zona)
nameVotes = getNameVotesByCandidate(numeros_consolidados_por_candidato)
cand1 = nameVotes.get('cand1')
cand2 = nameVotes.get('cand2')

Análise inicial dos dados

Escolheu-se analisar os locais de votação em Duque de Caxias, que naquela eleição, teve 230 locais

In [2]:
columns = [ 'Eleitores', 'Abstenções', 'Votos Nulos', 'Votos Brancos', 'DICA', 'WASHINGTON REIS' ]
indexes = [ 'Média', 'Mediana', 'Desvio Padrão', 'Variância' ]

aptos = getStatisticAnalysisByProp(df = df_local_votacao, prop = 'aptos')
nulos = getStatisticAnalysisByProp(df = df_local_votacao, prop = 'votos_nulos')
brancos = getStatisticAnalysisByProp(df = df_local_votacao, prop = 'votos_brancos')
abstencoes = getStatisticAnalysisByProp(df = df_local_votacao, prop = 'abstencoes')
dica = getStatisticAnalysisByProp(df = df_local_votacao, prop = 'DICA')
wr = getStatisticAnalysisByProp(df = df_local_votacao, prop = 'WASHINGTON REIS')
_dict = {
    'Eleitores': [ aptos.get('mean'), aptos.get('median'), aptos.get('std'), aptos.get('var') ],
    'Abstenções': [ abstencoes.get('mean'), abstencoes.get('median'), abstencoes.get('std'), abstencoes.get('var') ],
    'Votos Nulos': [ nulos.get('mean'), nulos.get('median'), nulos.get('std'), nulos.get('var') ],
    'Votos Brancos': [ brancos.get('mean'), brancos.get('median'), brancos.get('std'), brancos.get('var') ],
    'DICA': [ dica.get('mean'), dica.get('median'), dica.get('std'), dica.get('var') ],
    'WASHINGTON REIS': [ wr.get('mean'), wr.get('median'), wr.get('std'), wr.get('var') ]
}

pd.DataFrame(data = _dict, columns = columns, index = indexes)
Out[2]:
Eleitores Abstenções Votos Nulos Votos Brancos DICA WASHINGTON REIS
Média 2731 651 253 80 801 947
Mediana 2588 606 222 69 720 830
Desvio Padrão 1409 356 144 48 491 560
Variância 1985559 126884 20646 2351 240643 314069

Visualizando os dados

Visualizando os dados em geral

Proporção de eleitores considerados (votos válidos) em relação aos não considerados

In [3]:
values = [total_votos_validos, total_votos_nao_considerados]
labels = [ 'Computados', 'Desconsiderados' ]

title = 'O eleitorado divido em: votos computados e desconsiderados da apuração'
marker = {
    'colors': [ '#002AFF', '#FF5319' ]
}
fig = generatePieChart(go=go, labels=labels, values=values, title=title, marker=marker)
py.iplot(fig)
402,03064%226,13436%Export to plot.ly »
ComputadosDesconsideradosO eleitorado divido em: votos computados e desconsiderados da apuração

Como podemos ver, a porcentagem de eleitores não considerados, seja porque não votaram, anularam ou votaram branco, é grande, quando comparado com os eleitorado computado. Como vemos, cerca de 1/3 do eleitorado não foi contado naquela eleição.

Mas, e como ficaram a distribuição dos votos dos dois candidatos? No próximo diagrama, veremos como ficaram a distruibuição dos votos válidos.

Visualização da distribuição dos votos dos candidatos em segundo turno

In [4]:
values = [total_votos_nao_considerados, cand1.get('votes'), cand2.get('votes')]
labels = [ 'Não Computados', cand1.get('name'), cand2.get('name') ]

title = 'O eleitorado divido em: votos por candidato e desconsiderado na apuração'
marker = {
    'colors': [ '#FF5319', '#002AFF', '#401506' ]
}
fig = generatePieChart(go=go, labels=labels, values=values, title=title, marker=marker)
py.iplot(fig)
226,13436%217,80034.7%184,23029.3%Export to plot.ly »
Não ComputadosWASHINGTON REISDICAO eleitorado divido em: votos por candidato e desconsiderado na apuração

Como podemos ver, a quantidade de votos que o candidato Washington Reis teve, foi menor que a soma dos eleitores não considerados. Mas, se a apuração considerasse os votos do outro candidato mais os brancos e nulos?

Se ignorarmos as abstenções?

In [5]:
values = total_brancos + total_nulos
values = [ values, cand1.get('votes'), cand2.get('votes')]
labels = [ 'Nulos/Brancos', cand1.get('name'), cand2.get('name') ]

title = 'O eleitorado divido em: votos por candidato e desconsiderado na apuração'
marker = {
    'colors': [ '#FF5319', '#002AFF', '#401506' ]
}
fig = generatePieChart(go=go, labels=labels, values=values, title=title, marker=marker)
py.iplot(fig)
217,80045.5%184,23038.5%76,42016%Export to plot.ly »
WASHINGTON REISDICANulos/BrancosO eleitorado divido em: votos por candidato e desconsiderado na apuração

Ainda somando os votos nulos e brancos, com o segundo candidato Dica, temos mais votos Washington Reis.

  • Nulos / Brancos: 76.420
  • Dica: 184.230
  • Soma: 260.650
  • Diferença em relação ao candidato vencedor: 42.850

Faltaram então, 21.425 votos para que Washington tivesse a maioria dos votos, levando em consideração brancos e nulos

Como a eleição considera votos válidos, assim ficou o resultado

In [6]:
values = [cand1.get('votes'), cand2.get('votes')]
labels = [cand1.get('name'), cand2.get('name')]

title = 'A divisão dos votos válidos na eleição em 2016'
marker = {
    'colors': [ '#401506', '#8C2907' ]
}
fig = generatePieChart(go=go, labels=labels, values=values, title=title, marker=marker)
py.iplot(fig)
217,80054.2%184,23045.8%Export to plot.ly »
WASHINGTON REISDICAA divisão dos votos válidos na eleição em 2016

No gráfico a seguir, veremos como ficou a distribuição dos votos não considerados

Visualizando a divisão entre os não considerados

In [7]:
values = [total_abstencoes, total_brancos, total_nulos]
labels = [ 'Abstenções', 'Brancos', 'Nulos' ]

title = 'Proporcao de eleitores em votos válidos e desconsiderados na apuração'
marker = {
    'colors': [ '#FF5319', '#002AFF', '#401506' ]
}
fig = generatePieChart(go=go, labels=labels, values=values, title=title, marker=marker)
py.iplot(fig)
149,71466.2%58,08325.7%18,3378.11%Export to plot.ly »
AbstençõesNulosBrancosProporcao de eleitores em votos válidos e desconsiderados na apuração

Visualização com a distribuição dos votos dos candidatos em segundo turno

In [8]:
values = [cand1.get('votes'), cand2.get('votes'), total_abstencoes, total_brancos, total_nulos]
labels = [ cand1.get('name'), cand2.get('name'), 'Abstenções', 'Brancos', 'Nulos' ]

title = 'Proporcao de eleitores em votos por candidato e desconsiderados na apuração'
fig = generatePieChart(go=go, labels=labels, values=values, title=title)
py.iplot(fig)
217,80034.7%184,23029.3%149,71423.8%58,0839.25%18,3372.92%Export to plot.ly »
WASHINGTON REISDICAAbstençõesNulosBrancosProporcao de eleitores em votos por candidato e desconsiderados na apuração

Visualizando os dados por zona

O município de Duque de Caxias abrange 10 zonas eleitorais. Veremos como ficou a distribuição de eleitores e votos nas respectivas zonas

Proporção de eleitores considerados (votos válidos) em relação aos não considerados

In [9]:
agrupado_por_zona = getConsolidateNumbersByZona(df_secao)
zonas = agrupado_por_zona.index.values

_zonas = list(map(lambda z : 'Z-{}'.format(z), zonas))

props = ['votos_nominais', 'nao_considerados']
labels = { 'votos_nominais': 'Válidos', 'nao_considerados': 'Não Considerados' }
title = 'Proporção de eleitores em votos válidos e não considerados'
traces = generateDataToStackedBar(go=go, x=_zonas, props=props, labels=labels, df=agrupado_por_zona)
fig = generatedStackedBar(go=go, data=traces, title=title, x='Zonas', y='% de registros')
py.iplot(fig)
Z-66Z-77Z-78Z-79Z-103Z-126Z-127Z-128Z-194Z-200020406080100Export to plot.ly »
Não ConsideradosVálidosProporção de eleitores em votos válidos e não consideradosZonas% de registros

Visualizando a divisão entre os não considerados

In [10]:
title = 'Proporção de eleitores em votos válidos e divisão dos não considerados'
props = ['votos_nominais', 'abstencoes', 'votos_brancos', 'votos_nulos']
labels = { 'votos_nominais': 'Nominais', 'abstencoes' : 'Abstencoes', 'votos_brancos': 'Brancos', 'votos_nulos': 'Nulos' }
traces = generateDataToStackedBar(go=go, x=_zonas, props=props, labels=labels, df=agrupado_por_zona)
fig = generatedStackedBar(go=go, data=traces, title=title, x='Zonas', y='% de registros')
py.iplot(fig)
Z-66Z-77Z-78Z-79Z-103Z-126Z-127Z-128Z-194Z-200020406080100Export to plot.ly »
NulosBrancosAbstencoesNominaisProporção de eleitores em votos válidos e divisão dos não consideradosZonas% de registros

Visualização com a distribuição dos votos dos candidatos em segundo turno em relação aos votos não considerados

In [11]:
title = 'Proporção de eleitores que votaram em algum candidato e os que não foram considerados'
props = ['nao_considerados', 'DICA', 'WASHINGTON REIS']
labels = {
    'nao_considerados' : 'Não considerados',
    'DICA': 'DICA',
    'WASHINGTON REIS': 'WASHINGTON REIS'
}
traces = generateDataToStackedBar(go=go, x=_zonas, props=props, labels=labels, df=df_zona)
fig = generatedStackedBar(go=go, data=traces, title=title, x='Zonas', y='% de registros')
py.iplot(fig)
Z-66Z-77Z-78Z-79Z-103Z-126Z-127Z-128Z-194Z-200020406080100Export to plot.ly »
WASHINGTON REISDICANão consideradosProporção de eleitores que votaram em algum candidato e os que não foram consideradosZonas% de registros

Visualização com a distribuição dos votos dos candidatos em segundo turno em relação aos demais votos

In [12]:
title = 'Eleitores que votaram em algum candidato em votos brancos, nulos e abstenções'
props = ['abstencoes', 'votos_brancos', 'votos_nulos', 'DICA', 'WASHINGTON REIS']
labels = {
    'abstencoes' : 'Abstencoes',
    'votos_brancos': 'Brancos',
    'votos_nulos': 'Nulos',
    'DICA': 'DICA',
    'WASHINGTON REIS': 'WASHINGTON REIS'
}
traces = generateDataToStackedBar(go=go, x=_zonas, props=props, labels=labels, df=df_zona)
fig = generatedStackedBar(go=go, data=traces, title=title, x='Zonas', y='% de registros')
py.iplot(fig)
Z-66Z-77Z-78Z-79Z-103Z-126Z-127Z-128Z-194Z-200020406080100Export to plot.ly »
WASHINGTON REISDICANulosBrancosAbstencoesEleitores que votaram em algum candidato em votos brancos, nulos e abstençõesZonas% de registros

Visualizando os dados por seção

O objetivo aqui é trazer a dispersão dos votos e eleitores não considerados na apuração. O objetivo é entender se há uma certa lineridade nos dados. O número de seções está em ordem, haja vista que pode haver um mesmo número de seçao por zona. Veremos:

In [13]:
from scipy import stats

(test, pValue) = stats.shapiro(df_secao['abstencoes'])

print('Test: {}'.format(test))
print('p-value: {}'.format(pValue))
Test: 0.9976445436477661
p-value: 0.009883638471364975

Gráfico de dispersão e histograma das abstenções

In [14]:
title = 'Abstencoes por secao'
fig = generateScatterFigure(df_secao, go, 'abstencoes', title)
py.iplot(fig)
02004006008001000120014001600180020406080100120140160Export to plot.ly »
Abstencoes por secaoSeçãoNumeros absolutos
In [15]:
title = 'Abstencoes por secao'
fig = generateHistogramFigure(df_secao, go, 'abstencoes', title)
py.iplot(fig)
20406080100120140160050100150Export to plot.ly »
Abstencoes por secaoEleitoresProporção

Gráfico de dispersão e histograma dos votos nulos

In [16]:
title = 'Votos nulos por secao'
fig = generateScatterFigure(df_secao, go, 'votos_nulos', title)
py.iplot(fig)
02004006008001000120014001600180001020304050607080Export to plot.ly »
Votos nulos por secaoSeçãoNumeros absolutos
In [17]:
title = 'Votos nulos por secao'
fig = generateHistogramFigure(df_secao, go, 'votos_nulos', title, 80)
py.iplot(fig)
10203040506070020406080100120140160Export to plot.ly »
Votos nulos por secaoEleitoresProporção

Gráfico de dispersão dos votos brancos

In [18]:
title = 'Votos brancos por secao'
fig = generateScatterFigure(df_secao, go, 'votos_brancos', title)
py.iplot(fig)
020040060080010001200140016001800051015202530Export to plot.ly »
Votos brancos por secaoSeçãoNumeros absolutos
In [19]:
title = 'Votos Brancos por secao'
fig = generateHistogramFigure(df_secao, go, 'votos_brancos', title, 130)
py.iplot(fig)
051015202530020406080100120140160Export to plot.ly »
Votos Brancos por secaoEleitoresProporção

Referências

Resultado das eleições em dados.gov