import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import re
import plotly
import plotly.plotly as py
import plotly.graph_objs as go
# Llenar credenciales para poder reroducir gráficas en Plotly:
plotly.tools.set_credentials_file(username='', api_key='')
pd.options.display.max_colwidth = 300
dir_datos = 'D:/datos/presupuesto_mexico'
%matplotlib inline
deflactor = pd.read_excel('datos/inflacion_acumulada_1970_2018.xls', header=3, skipfooter=5)\
.assign(year=lambda x: x['Periodo'].str[0:4].astype(int),
mes=lambda x: x['Periodo'].str[5:].astype(int))\
.rename(columns={'Índice general ': 'inpc'})\
.query('mes==12')\
.sort_values('year')\
.set_index('year')\
.assign(indice=lambda x: x['inpc'].apply(lambda x: (1+x/100)).cumprod())\
.assign(deflactor=lambda x: x.loc[2018, 'indice']/x['indice'])\
.reset_index()\
[['year', 'deflactor']]\
.append(pd.DataFrame([{'year': 2019, 'deflactor': 0.9671}]), sort=True)
deflactor.to_csv('datos/deflactor_2018.csv', index=False)
df = pd.concat([pd.read_csv(f'{dir_datos}/{y}.csv') for y in range(2013, 2020)])
df.to_csv(f'{dir_datos}/presupuesto_2013_2019.csv', index=False)
deflactor = pd.read_csv('datos/deflactor_2018.csv').query('year>=2013')
df = pd.read_csv(f'{dir_datos}/presupuesto_2013_2019.csv')\
.assign(ID_PP=lambda x: x['ID_PP'].astype(str).str.zfill(3))\
.assign(id_pp=lambda x: x['ID_MODALIDAD']+x['ID_PP'])\
.set_index('CICLO')
df['aprobado'] = (df['MONTO_APROBADO']*deflactor.set_index('year')['deflactor'])
df.reset_index(inplace=True)
dh = df.loc[df['DESC_PP'].str.contains('derechos humanos', case=False)|
df['DESC_RAMO'].str.lower().str.contains('derechos humanos', case=False)]\
.assign(ID_PP=lambda x: x['ID_PP'].astype(str).str.zfill(3))\
.assign(id_pp=lambda x: x['ID_MODALIDAD']+x['ID_PP'])\
.set_index('CICLO')
dh['aprobado'] = (dh['MONTO_APROBADO']*deflactor.set_index('year')['deflactor'])
dh['ejercicio'] = dh['MONTO_EJERCICIO']*deflactor.set_index('year')['deflactor']
dh['ejercido'] = dh['MONTO_EJERCIDO']*deflactor.set_index('year')['deflactor']
dh['modificado'] = dh['MONTO_MODIFICADO']*deflactor.set_index('year')['deflactor']
dh['devengado'] = dh['MONTO_DEVENGADO']*deflactor.set_index('year')['deflactor']
dh['pagado'] = dh['MONTO_PAGADO']*deflactor.set_index('year')['deflactor']
dh.to_csv(f'presupuesto_ddhh_2013_2019.csv', index=True)
# Entradas y salidas de PPs
writer = pd.ExcelWriter('entradas_salidas_pp.xlsx', engine='xlsxwriter')
dh.groupby(['CICLO', 'DESC_RAMO']).apply(lambda x: set(x['id_pp'].unique().tolist())).to_frame('pp')\
.assign(entran=lambda z: z.groupby('DESC_RAMO').transform(lambda y: y.diff(1)),
salen=lambda z: z.groupby('DESC_RAMO').transform(lambda y: y.diff(-1).shift(1)))\
.to_excel(writer, sheet_name='year_ramo')
#.assign(acumulado=lambda z: z.groupby(['DESC_RAMO'])['pp'].apply(lambda v: v.apply(list).cumsum().apply(set).shift(2)))\
#.assign(reingreso=lambda u: u['entran']-u['entran'])
dh.groupby(['CICLO']).apply(lambda x: set(x['id_pp'].unique().tolist())).to_frame('pp')\
.assign(entran=lambda z: z['pp'].diff(1),
salen=lambda z: z['pp'].diff(-1).shift(1))\
.to_excel(writer, sheet_name='year')
writer.save()
dh = pd.read_csv('datos/presupuesto_ddhh_2013_2019.csv') / 1000000
df = pd.read_csv(dir_datos+'/presupuesto_2013_2019.csv')
deflactor = pd.read_csv('datos/deflactor_2018.csv').query('year>=2013')
dh.set_index('CICLO', inplace=True)
# Add data
dh_total = dh.groupby(['CICLO'])['aprobado'].sum().reset_index()
# Create and style traces
data = [go.Scatter(
x = dh_total['CICLO'],
y = dh_total['aprobado']/1000000,
line = dict(
color = ('rgb(205, 12, 24)'),
width = 4)
)]
# Edit the layout
layout = dict(title = 'Gasto en programas presupuestarios de Derechos Humanos',
xaxis = dict(title = ''),
yaxis = dict(title = 'Millone de pesos (2018)',
rangemode='tozero', autorange=True),
)
fig = dict(data=data, layout=layout)
py.iplot(fig, filename='presup-ddhh-total')
dicc_ramos = {'Comisión Nacional de los Derechos Humanos': 'CNDH',
'Defensa Nacional': 'Defensa',
'Instituto Nacional de Transparencia, Acceso a la Información y Protección de Datos Personales': 'INAI',
'Gobernación': 'SEGOB',
'Procuraduría General de la República': 'PGR',
'Relaciones Exteriores': 'SRE',
'Seguridad Pública': 'SSP'}
dh_ramo = dh.query('CICLO==2019').groupby(['DESC_RAMO'])[['aprobado']].sum()
data_ramo = (100*(dh_ramo/dh_ramo.sum())).reset_index().replace({'DESC_RAMO': dicc_ramos})
fig = {
"data": [
{
"values": data_ramo['aprobado'].tolist(),
"labels": data_ramo['DESC_RAMO'].tolist(),
"domain": {"x": [0, 1]},
"hoverinfo":"label+percent",
"hole": .6,
"type": "pie"
}],
"layout": {
"title":"Distribución del presupuesto en DDHH por ramo, 2019",
"annotations": [
{
"font": {
"size": 20
},
"showarrow": False,
"text": "Participación <br> %",
"x": 0.5,
"y": 0.5
},
]
}
}
py.iplot(fig, filename='presup-ddhh-ramos')
[x for x in dh.query('CICLO==[2018, 2019]').DESC_PP.unique() if re.search('mujer|niñ|lgbt|migra|period|sex|desap|indig', x, re.I)]
dicc_replace_hm = {'realizar la promoción y observancia en el monitoreo, seguimiento y evaluación del impacto de la política nacional en materia de igualdad entre mujeres y hombres':
'promover, divulgar, dar seguimiento, evaluar y monitorear la política nacional en materia de igualdad entre mujeres y hombres, y atender asuntos de la mujer',
'atender asuntos relacionados con personas reportadas como desaparecidas, extraviadas, ausentes y fallecidas no identificadas':
'atender asuntos relacionados con personas reportadas como desaparecidas y no localizadas'}
pps_dh = [x for x in dh.query('CICLO==[2018, 2019]').DESC_PP.unique() if re.search('mujer|niñ|lgbt|migra|period|sex|desap', x, re.I)]
dh_pp_cndh = dh.query('DESC_PP==@pps_dh & CICLO==[2018, 2019]')\
.assign(pp=lambda x: (x['DESC_PP'].str.replace('.', '').str.lower())\
.replace(dicc_replace_hm))\
.groupby(['CICLO', 'pp']).sum()[['aprobado']]\
.unstack(0).reset_index().sort_values(('aprobado', 2018))
dh_pp_cndh['diff'] = dh_pp_cndh['aprobado'][2018]-dh_pp_cndh['aprobado'][2019]
dicc_pp_cndh = {'atender asuntos relacionados con sexualidad, salud y vih': 'Sexualidad,<br> salud<br> y VIH',
'atender asuntos relacionados con niñas, niños y adolescentes': 'Niñas,<br> niños y <br> adolescentes',
'promover el respeto de los derechos humanos de periodistas y personas defensores de derechos humanos': 'Periodistas <br> y defensores<br> de DDHH',
'promover, divulgar, dar seguimiento, evaluar y monitorear la política nacional en materia de igualdad entre mujeres y hombres, y atender asuntos de la mujer': 'Igualdad<br> de género',
'atender asuntos relacionados con las personas migrantes': 'Personas <br>migrantes',
'atender asuntos relacionados con personas reportadas como desaparecidas y no localizadas': 'Personas<br> desaparecidas'}
dh_pp_cndh['var_procentual'] = 100*(dh_pp_cndh['diff']/dh_pp_cndh['aprobado'][2018])
dh_pp_cndh
x = dh_pp_cndh['pp'].map(dicc_pp_cndh)
trace1 = {
'x': dh_pp_cndh['aprobado'][2019],
'y': x,
'hovertext': '2019',
"hoverinfo":"text",
'name': '2019',
'type': 'bar',
'orientation': 'h',
'marker': dict(
color='rgba(55, 128, 191, 0.7)',
line=dict(
color='rgba(55, 128, 191, 1.0)',
width=2,
)
)
};
trace2 = {
'x': dh_pp_cndh['aprobado'][2018],
'y': x,
'hovertext': '2018',
"hoverinfo":"text",
'name': '2018',
'type': 'bar',
'orientation': 'h',
'marker': dict(
color='rgba(219, 64, 82, 0.7)',
line=dict(
color='rgba(219, 64, 82, 1.0)',
width=2,
)
)
};
data = [trace1, trace2];
layout = {
'xaxis': {'title': ''},
'xaxis': {'title': 'Millones de pesos (a precios de 2018 )'},
'title': 'Gasto en programas de población específica de la CNDH'
};
py.iplot({'data': data, 'layout': layout}, filename='presup-cndh')
dh_pp_otros['var_procentual'] = 100*(dh_pp_otros['diff']/(dh_pp_otros['aprobado'][2018]))
dh_pp_otros
dh_pp_otros= (dh.query('ID_RAMO==[7, 4, 17] & CICLO==[2018, 2019]')\
.assign(pp=lambda x: (x['DESC_PP'].str.lower()))\
.groupby(['CICLO', 'pp']).sum()/1000000)[['aprobado']]\
.unstack(0)\
.reset_index()\
.sort_values(('aprobado', 2019), ascending=True)
dh_pp_otros['diff'] = dh_pp_otros['aprobado'][2018]-dh_pp_otros['aprobado'][2019]
dicc_pp_otros = {'derechos humanos': 'Derechos<br> Humanos<br> (Defensa)',
'programa de derechos humanos': 'Programa <br> DDHH <br> (SEGOB)',
'promover la protección de los derechos humanos y prevenir la discriminación': 'Prevenir <br> discriminación <br> (SEGOB)',
'promoción del respeto a los derechos humanos y atención a víctimas del delito': 'Respeto<br> victimas <br> delito <br> (PGR)'}
x = dh_pp_otros['pp'].map(dicc_pp_otros)
trace1 = {
'x': dh_pp_otros['aprobado'][2019],
'y': x,
'hovertext': '2019',
"hoverinfo":"text",
'name': '2019',
'type': 'bar',
'orientation': 'h',
'marker': dict(
color='rgba(55, 128, 191, 0.7)',
line=dict(
color='rgba(55, 128, 191, 1.0)',
width=2,
)
)
};
trace2 = {
'x': dh_pp_otros['aprobado'][2018],
'y': x,
'hovertext': '2018',
"hoverinfo":"text",
'name': '2018',
'type': 'bar',
'orientation': 'h',
'marker': dict(
color='rgba(219, 64, 82, 0.7)',
line=dict(
color='rgba(219, 64, 82, 1.0)',
width=2,
)
)
};
data = [trace1, trace2];
layout = {
'xaxis': {'title': ''},
'xaxis': {'title': 'Millones de pesos (a precios de 2018 )'},
'title': 'Gasto en programas de DDHH, en los ramos Defensa, SEGOB y PGR',
};
py.iplot({'data': data, 'layout': layout}, filename='presup-ddhh-otros')
dh.query('CICLO==2019')\
.groupby('ENTIDAD_FEDERATIVA')['aprobado'].sum()/1000000
dh_ent = dh.query('CICLO==2019 & ENTIDAD_FEDERATIVA!="Ciudad de México"')\
.replace({'ENTIDAD_FEDERATIVA': {'Baja California Sur': 'BCS'}})\
.groupby('ENTIDAD_FEDERATIVA')['aprobado'].sum()\
.reset_index()\
.sort_values('aprobado', ascending=False)
trace1 = {
'x': dh_ent['ENTIDAD_FEDERATIVA'],
'y': dh_ent['aprobado']/1000000,
'type': 'bar',
'orientation': 'v',
'marker': dict(
color='rgba(55, 128, 191, 0.7)',
line=dict(
color='rgba(55, 128, 191, 1.0)',
width=2,
)
)
}
data = [trace1];
layout = {
'xaxis': {'title': ''},
'yaxis': {'title': 'Millones de pesos (a precios de 2018 )'},
'title': 'Gasto en programas presupuestales de DDHH, por entidad, 2019',
'annotations': [
dict(
x=0,
y=-0.25,
showarrow=False,
text='Nota: excluimos la Ciudad de México para evitar problemas con la escala.',
xref='paper',
yref='paper'
)]
};
py.iplot({'data': data, 'layout': layout}, filename='presup-ddhh-entidad')
dh.keys()
dh_conc = dh.assign(concepto=lambda x: (x['DESC_CONCEPTO'].str.replace('.', '').str.lower()))\
.query('CICLO==2019')\
.groupby(['concepto']).sum()\
.sort_values('aprobado', ascending=False)\
[['aprobado']]\
.reset_index()\
.iloc[0:10]
trace1 = {
'x': dh_conc['concepto'],
'y': dh_ent['aprobado']/1000000,
'type': 'bar',
'orientation': 'v',
'marker': dict(
color='rgba(55, 128, 191, 0.7)',
line=dict(
color='rgba(55, 128, 191, 1.0)',
width=2,
)
)
}
data = [trace1];
layout = {
'xaxis': {'title': ''},
'yaxis': {'title': 'Millones de pesos (a precios de 2018 )'},
'title': 'Top 10 conceptos de gasto en programas presupuestales de DDHH, 2019',
};
py.iplot({'data': data, 'layout': layout}, filename='presup-ddhh-concepto')
df_conc = df.assign(concepto=lambda x: (x['DESC_CONCEPTO'].str.replace('.', '').str.lower()))\
.groupby(['concepto']).sum()
dh_conc
pres_total = (((df.groupby(['CICLO']).sum()['MONTO_APROBADO'])*deflactor.set_index('year')['deflactor'])/1000000000000).reset_index()
prop_dh = (100*(dh.groupby(['CICLO']).sum()['aprobado']/((df.groupby(['CICLO']).sum()['MONTO_APROBADO'])*deflactor.set_index('year')['deflactor'])))\
.reset_index()
trace1 = go.Scatter(
x=prop_dh['CICLO'],
y=prop_dh[0],
name='Presupuesto en DDHH <br> (eje izquierdo)'
)
trace2 = go.Scatter(
x=pres_total['CICLO'],
y=pres_total[0],
name='Presupuesto total <br> (eje derecho)',
yaxis='y2'
)
data = [trace1, trace2]
layout = go.Layout(
title='Proporción que representan los programas presupuestales en DDHH <br> en el presupuesto total',
yaxis=dict(
title='Porcentaje del presupuesto total'
),
yaxis2=dict(
title='Billones de pesos <br>(a precios de 2018)',
titlefont=dict(
color='rgb(148, 103, 189)'
),
tickfont=dict(
color='rgb(148, 103, 189)'
),
overlaying='y',
side='right'
)
)
fig = go.Figure(data=data, layout=layout)
py.iplot(fig, filename='presup-ddhh-prop')
#http://www.cndh.org.mx/Cifras_sobre_actividades_CNDH
recom = pd.read_excel('datos/recomendaciones_CNDH.xlsx')
trace1 = {
'x': recom['year'],
'y': recom['recomendaciones'],
'type': 'bar',
'orientation': 'v',
'marker': dict(
color='rgba(55, 128, 191, 0.7)',
line=dict(
color='rgba(55, 128, 191, 1.0)',
width=2,
)
)
}
data = [trace1];
layout = {
'xaxis': {'title': ''},
'yaxis': {'title': 'Número de recomendaciones'},
'title': 'Recomendaciones emitidas por la CNDH',
};
py.iplot({'data': data, 'layout': layout}, filename='recomendaciones-cndh')
presup_ramos_year = (dh.groupby(['DESC_RAMO', 'CICLO'])[['aprobado']].sum()/1000000).reset_index()\
.assign(ramo=lambda x: x['DESC_RAMO'].map(dicc_ramos))
presup_ramos_year.to_csv('datos/presup_ramo_year.csv', index=False)
dh.keys()
presup_tipogasto_year = (dh.groupby(['DESC_RAMO', 'CICLO', 'DESC_TIPOGASTO'])[['aprobado']].sum()/1000000).reset_index()\
.assign(ramo=lambda x: x['DESC_RAMO'].map(dicc_ramos))
presup_tipogasto_year.to_csv('datos/presup_tipogasto_year.csv', index=False)
presup_tipogasto_year
dh_concepto = dh.groupby(['DESC_RAMO', 'CICLO', 'DESC_CONCEPTO']).apply(lambda x: x[['aprobado']].sum())\
.groupby(['DESC_RAMO', 'CICLO'])\
.apply(lambda y: y.sort_values( 'aprobado',ascending=False).iloc[1:10])
dh_concepto.index = dh_concepto.index.droplevel([2,3])
dh_concepto.to_csv('presup_top10_concepto_ramo_year.csv', index=False)
df.query('CICLO==2014')['MONTO_APROBADO'].sum()
df.DESC_PP.isnull().sum()