OverviewΒΆ

1 in 7 children in the United States lives in poverty, raising stress and crime rates, worsening educational outcomes, and shrinking the economy by up to $1 trillion annually. Research shows that giving money to families with children, as most developed countries do, reduces each of these issues. A child allowance is a policy that gives families an equal amount for each child.

This project examines child allowances through various lenses:

  • Simulations quantifying the effects of child allowance policies (deficit- and tax-funded) on poverty and inequality across US states.

  • Research on the effects of child allowances and similar policies on children, based on randomized controlled trials and other empirical techniques.

  • Policy context of existing US child benefits and child allowances in other countries.

For example, this interactive map is one of several visualizations in our simulations page.

# TODO: Add tax reforms as a drop-down (mirrored from simulation.ipynb).

# Imports.
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

# Load data.
summary = pd.read_csv('https://github.com/ngpsu22/Child_Allowance_States/raw/main/poverty_gini_tax_child_allowance')

# General configs.
LABELS = {'monthly_ca': 'Monthly child allowance',
          'decile': 'Decile',
          'net_chg': 'Net change',
          'pct_chg': 'Net change',
          'child_allowance':'Monthly child allowance',
          'code': 'State',
          'state': 'State',
          'fed_tax_rate': 'Tax rate',
          'state_tax_rate': 'Tax rate',
          'non_funded_poverty_rate': 'Poverty rate',
          'fed_poverty_rate': 'Poverty rate',
          'state_poverty_rate': 'Poverty rate',
          'non_funded_gini': 'Gini index',
          'fed_gini': 'Gini index',
          'state_gini': 'Gini index'}

CONFIG = {'displayModeBar': False}

# Preprocess data.
summary.drop('Unnamed: 0', 1, inplace = True)
state_dict = summary[['code', 'state']].set_index('code').to_dict()['state']

# data labels
FUNDING = {'fed_poverty_rate': 'Federal tax',
           'state_poverty_rate': 'State tax',
           'non_funded_poverty_rate': 'No funding'}

ca_amts = summary.child_allowance.unique()
child_poverty = summary[(summary['age_group'] == 'child') &
                        (summary['race'] == 'All')]

# create figure dictionary
fig_dict = {
    'data': [],
    'layout': {},
    'frames': []
}

# fill in most of layout
fig_dict['layout'] = {
    'plot_bgcolor': 'white',
    'font': dict(family = 'Roboto'),
    'height': 600,
    'margin': dict(t=100, b=0, l=0, r=10)
}
fig_dict['layout']['title'] = {
    'text': ('Child poverty by state and child allowance amount'),
    'y': 0.97,
    'x': 0.05,
    'xanchor': 'left',
    'yanchor': 'top'
}

# add slider specifications
slidermenu =  {
    'buttons': [
        {
            'args': [None, {'frame': {'duration': 500, 'redraw': True},
                            'fromcurrent': True,
                            'transition': {'duration': 300,
                                           'easing': 'quadratic-in-out'}}],
            'label': '▶',
            'method': 'animate'
        },
        {
            "args": [[None], {"frame": {"duration": 0, "redraw": True},
                              "mode": "immediate",
                              "transition": {"duration": 0}}],
            "label": "◼",
            "method": "animate"
        }
    ],
    'direction': 'left',
    'pad': {'r': 15, 't': 75},
    'showactive': True,
    'type': 'buttons',
    'x': 0.1,
    'xanchor': 'right',
    'y': 0,
    'yanchor': 'top'
}
    
sliders_dict = {
    'active': 0,
    'yanchor': 'top',
    'xanchor': 'left',
    'currentvalue': {
        'font': {'size': 20},
        'prefix': 'Monthly child allowance: ',
        'visible': True,
        'xanchor': 'right'
    },
    'transition': {'duration': 300, 'easing': 'cubic-in-out'},
    'pad': {'b': 10, 't': 50},
    'len': 0.9,
    'x': 0.1,
    'y': 0,
    'steps': []
}

steps = []
for ca in ca_amts:
    slider_step = {
        'args': [
            [ca],
            {'frame': {'duration': 300, 'redraw': True},
             'mode': 'immediate',
             'transition': {'duration': 300}}
        ],
        'label': '$' + str(ca),
        'method': 'animate'
    }
    steps.append(slider_step)
sliders_dict['steps'] = steps

# generate frames
frames = []
locations = child_poverty.code
zero_poverty = child_poverty[child_poverty.child_allowance == 0]
for ca in ca_amts:
    data_list = []
    ca_data = child_poverty[child_poverty.child_allowance == ca]
    for funding in FUNDING:
        data_list.append({
            'hovertemplate': 
                '<b>%{customdata[1]}</b>' + 
                '<br>Child poverty rate: %{z}%<br>' + 
                'Poverty reduction: %{customdata[0]}%' +
                '<extra></extra>',
            'locationmode': 'USA-states',
            'locations': child_poverty.code.unique(),
            'z': ca_data[funding].tolist(),
            'type': 'choropleth',
            'customdata': list(map(lambda x, y, z: (round(100 * (1 - y / x)), state_dict[z]),
                                   zero_poverty[funding], ca_data[funding], state_dict))
        })
    
    frame = {'data': data_list, 'name': str(ca), 'traces': [0,1,2]}
    frames.append(frame)
    
# add frames to figure dictionary
fig_dict['frames'] = frames

# add traces to figure dictionary
for i in (range(len(FUNDING))):
    fig_dict['data'].append(frames[0]['data'][0])

# generate figure
fig = go.Figure(fig_dict)

# generate dropdown menu buttons
buttons = []
for funding in FUNDING:
    new_button = {'method': 'update',
                  'label': FUNDING[funding],
                  'args': [{'visible': [f == funding for f in FUNDING.keys()]}
                          ]}
    buttons.append(new_button)
    
# construct button menu
updatemenu = {'buttons': buttons,
              'direction': 'down',
              'showactive': True,
              'pad':{"r": 10, 't': 20, 'l': 50},
              'xanchor': 'left',
              'yanchor': 'top',
              'x': 0,
              'y': 1.2
             }

# add slider, dropdown menu, and set geo scope
fig.update_layout(
    geo_scope='usa', # limite map scope to USA
    sliders=[sliders_dict],
    updatemenus=[slidermenu, updatemenu]
)

# update visual attributes
fig.update_traces(showscale=False, colorscale='Reds', zmin=0, zmax=22)
fig.update_layout(
    hoverlabel=dict(
        bgcolor="white",
        font=dict(family='Roboto')
    ),
    title_font_size=20,
)
fig.update(layout_showlegend=False)

fig.show(config=CONFIG)