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)

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)

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)

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)

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)

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)

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)

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)

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)

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)

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)
In [15]:
title = 'Abstencoes por secao'
fig = generateHistogramFigure(df_secao, go, 'abstencoes', title)
py.iplot(fig)

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)
In [17]:
title = 'Votos nulos por secao'
fig = generateHistogramFigure(df_secao, go, 'votos_nulos', title, 80)
py.iplot(fig)

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)
In [19]:
title = 'Votos Brancos por secao'
fig = generateHistogramFigure(df_secao, go, 'votos_brancos', title, 130)
py.iplot(fig)

Referências

Resultado das eleições em dados.gov