Skip to content

Instantly share code, notes, and snippets.

@nikhilwoodruff
Last active July 20, 2023 19:52
Show Gist options
  • Select an option

  • Save nikhilwoodruff/447d86032ff481bdeb1e35aeeb3ea18c to your computer and use it in GitHub Desktop.

Select an option

Save nikhilwoodruff/447d86032ff481bdeb1e35aeeb3ea18c to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Modelling code for PolicyEngine's two-child limit analysis"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [],
"source": [
"from policyengine_uk import Microsimulation\n",
"from policyengine_core.reforms import Reform\n",
"from policyengine_core.periods import instant\n",
"import pandas as pd\n",
"from policyengine_core.charts import *\n",
"\n",
"\n",
"def modify_parameters(parameters):\n",
" parameters.gov.dwp.universal_credit.elements.child.limit.child_count.update(start=instant(\"2023-01-01\"), stop=instant(\"2028-12-31\"), value=99)\n",
" parameters.gov.dwp.tax_credits.child_tax_credit.limit.child_count.update(start=instant(\"2023-01-01\"), stop=instant(\"2028-12-31\"), value=99) \n",
" return parameters\n",
"\n",
"\n",
"class reform(Reform):\n",
" def apply(self):\n",
" self.modify_parameters(modify_parameters)\n",
"\n",
"\n",
"baseline = Microsimulation()\n",
"baseline.default_calculation_period = 2023\n",
"reformed = Microsimulation(reform=reform)\n",
"reformed.default_calculation_period = 2023"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1.7762205605125427"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Children affected\n",
"has_gain = reformed.calculate(\"household_net_income\", 2023) - baseline.calculate(\"household_net_income\", 2023) > 0\n",
"children_in_household = baseline.calculate(\"is_child\", map_to=\"household\")\n",
"(children_in_household * has_gain).sum()/1e6"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1.8052459887296664"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Net cost\n",
"reformed.calculate(\"household_net_income\", 2023).sum()/1e9 - baseline.calculate(\"household_net_income\", 2023).sum()/1e9"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Make a table of person-level results\n",
"\n",
"df = pd.DataFrame(dict(\n",
" is_child=baseline.calculate(\"is_child\"),\n",
" household_net_income_baseline=baseline.calculate(\"household_net_income\", map_to=\"person\"),\n",
" household_net_income_reformed=reformed.calculate(\"household_net_income\", map_to=\"person\"),\n",
" in_poverty_baseline=baseline.calculate(\"in_poverty\", map_to=\"person\"),\n",
" in_poverty_reformed=reformed.calculate(\"in_poverty\", map_to=\"person\"),\n",
" in_poverty_ahc_baseline=baseline.calculate(\"in_poverty_ahc\", map_to=\"person\"),\n",
" in_poverty_ahc_reformed=reformed.calculate(\"in_poverty_ahc\", map_to=\"person\"),\n",
" in_relative_poverty_ahc_baseline=baseline.calculate(\"in_relative_poverty_ahc\", map_to=\"person\"),\n",
" in_relative_poverty_ahc_reformed=reformed.calculate(\"in_relative_poverty_ahc\", map_to=\"person\"),\n",
" household_weight=baseline.calculate(\"household_weight\", map_to=\"person\"),\n",
" tax_credits_baseline=baseline.calculate(\"tax_credits\", map_to=\"person\"),\n",
" tax_credits_reformed=reformed.calculate(\"tax_credits\", map_to=\"person\"),\n",
" universal_credit_baseline=baseline.calculate(\"universal_credit\", map_to=\"person\"),\n",
" universal_credit_reformed=reformed.calculate(\"universal_credit\", map_to=\"person\"),\n",
" uc_child_limit_affected_baseline=baseline.calculate(\"uc_child_limit_affected\", map_to=\"person\"),\n",
" uc_child_limit_affected_reformed=reformed.calculate(\"uc_child_limit_affected\", map_to=\"person\"),\n",
" ctc_child_limit_affected_baseline=baseline.calculate(\"ctc_child_limit_affected\", map_to=\"person\"),\n",
" ctc_child_limit_affected_reformed=reformed.calculate(\"ctc_child_limit_affected\", map_to=\"person\"),\n",
"))\n",
"\n",
"df[\"gain\"] = df[\"household_net_income_reformed\"] - df[\"household_net_income_baseline\"]\n",
"df[\"affected_by_child_limit\"] = df.gain > 0"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.5090657973365784"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Number of households affected\n",
"\n",
"gain = reformed.calculate(\"household_net_income\", 2023) - baseline.calculate(\"household_net_income\", 2023)\n",
"\n",
"(gain > 0).sum()/1e6"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
"# Make a table of person-level results\n",
"\n",
"df = pd.DataFrame(dict(\n",
" is_child=baseline.calculate(\"is_child\"),\n",
" household_net_income_baseline=baseline.calculate(\"household_net_income\", map_to=\"person\"),\n",
" household_net_income_reformed=reformed.calculate(\"household_net_income\", map_to=\"person\"),\n",
" in_poverty_baseline=baseline.calculate(\"in_poverty\", map_to=\"person\"),\n",
" in_poverty_reformed=reformed.calculate(\"in_poverty\", map_to=\"person\"),\n",
" in_poverty_ahc_baseline=baseline.calculate(\"in_poverty_ahc\", map_to=\"person\"),\n",
" in_poverty_ahc_reformed=reformed.calculate(\"in_poverty_ahc\", map_to=\"person\"),\n",
" in_relative_poverty_ahc_baseline=baseline.calculate(\"in_relative_poverty_ahc\", map_to=\"person\"),\n",
" in_relative_poverty_ahc_reformed=reformed.calculate(\"in_relative_poverty_ahc\", map_to=\"person\"),\n",
" household_weight=baseline.calculate(\"household_weight\", map_to=\"person\", period=2023),\n",
" on_universal_credit_baseline=baseline.calculate(\"universal_credit\", map_to=\"person\") > 0,\n",
" uc_child_limit_affected_baseline=baseline.calculate(\"uc_child_limit_affected\", map_to=\"person\"),\n",
" uc_child_limit_affected_reformed=reformed.calculate(\"uc_child_limit_affected\", map_to=\"person\"),\n",
" ctc_child_limit_affected_baseline=baseline.calculate(\"ctc_child_limit_affected\", map_to=\"person\"),\n",
" ctc_child_limit_affected_reformed=reformed.calculate(\"ctc_child_limit_affected\", map_to=\"person\"),\n",
" universal_credit_baseline=baseline.calculate(\"universal_credit\", map_to=\"person\"),\n",
" universal_credit_reformed=reformed.calculate(\"universal_credit\", map_to=\"person\"),\n",
" child_tax_credit_baseline=baseline.calculate(\"child_tax_credit\", map_to=\"person\"),\n",
" child_tax_credit_reformed=reformed.calculate(\"child_tax_credit\", map_to=\"person\"),\n",
" \n",
" UC_individual_child_element_baseline=baseline.calculate(\"UC_individual_child_element\", map_to=\"person\"),\n",
" UC_individual_child_element_reformed=reformed.calculate(\"UC_individual_child_element\", map_to=\"person\"),\n",
"))\n",
"\n",
"df[\"gain\"] = df[\"household_net_income_reformed\"] - df[\"household_net_income_baseline\"]\n",
"df[\"affected_by_child_limit\"] = df.gain > 0"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1317376.6"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Number of children who are a) affected and b) in relative ahc poverty in baseline and c) still in relative ahc poverty in reformed, \n",
"# used to benchmark CPAG's 850k children brought into less deep poverty estimate \n",
"\n",
"df[df.affected_by_child_limit * df.is_child * df.in_relative_poverty_ahc_baseline * df.in_relative_poverty_ahc_reformed].household_weight.sum()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1.7762205"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Total children affected by the policy (benchmarking against CPAG)\n",
"df[df.is_child * df.affected_by_child_limit].household_weight.sum()/1e6"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>year</th>\n",
" <th>cost</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>2023</td>\n",
" <td>1.805246</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2024</td>\n",
" <td>2.951946</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2025</td>\n",
" <td>2.804540</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" year cost\n",
"0 2023 1.805246\n",
"1 2024 2.951946\n",
"2 2025 2.804540"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# get cost in each year from 2023 to 2028\n",
"\n",
"costs = []\n",
"for year in range(2023, 2026):\n",
" cost = reformed.calculate(\"household_net_income\", year).sum()/1e9 - baseline.calculate(\"household_net_income\", year).sum()/1e9\n",
" costs.append(cost)\n",
"\n",
"pd.DataFrame(dict(year=range(2023, 2026), cost=costs))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>year</th>\n",
" <th>cost</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>2023</td>\n",
" <td>-162.570394</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2024</td>\n",
" <td>-405.433993</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2025</td>\n",
" <td>-319.325404</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" year cost\n",
"0 2023 -162.570394\n",
"1 2024 -405.433993\n",
"2 2025 -319.325404"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Get child poverty headcount reduction in each year from 2023 to 2026\n",
"\n",
"costs = []\n",
"for year in range(2023, 2026):\n",
" child_poverty_baseline = (baseline.calculate(\"in_relative_poverty_ahc\", year, map_to=\"person\") * baseline.calculate(\"is_child\")).sum() / 1e3\n",
" child_poverty_reformed = (reformed.calculate(\"in_relative_poverty_ahc\", year, map_to=\"person\") * reformed.calculate(\"is_child\")).sum() / 1e3\n",
" costs.append(child_poverty_reformed - child_poverty_baseline)\n",
"\n",
"pd.DataFrame(dict(year=range(2023, 2026), cost=costs))"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>year</th>\n",
" <th>cost</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>2023</td>\n",
" <td>-307.552986</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2024</td>\n",
" <td>-497.361415</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2025</td>\n",
" <td>-407.959079</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" year cost\n",
"0 2023 -307.552986\n",
"1 2024 -497.361415\n",
"2 2025 -407.959079"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Get child poverty headcount reduction in each year from 2023 to 2026\n",
"\n",
"costs = []\n",
"for year in range(2023, 2026):\n",
" child_poverty_baseline = (baseline.calculate(\"in_poverty\", year, map_to=\"person\") * baseline.calculate(\"is_child\")).sum() / 1e3\n",
" child_poverty_reformed = (reformed.calculate(\"in_poverty\", year, map_to=\"person\") * reformed.calculate(\"is_child\")).sum() / 1e3\n",
" costs.append(child_poverty_reformed - child_poverty_baseline)\n",
"\n",
"pd.DataFrame(dict(year=range(2023, 2026), cost=costs))"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Baseline: 11.8%, reformed: 11.1%\n",
"Baseline: 7,757k, reformed: 7,309k, change: -448k\n",
"Baseline: 13.0%, reformed: 11.9%\n",
"Baseline: 8,590k, reformed: 7,868k, change: -722k\n",
"Baseline: 14.3%, reformed: 13.4%\n",
"Baseline: 9,405k, reformed: 8,816k, change: -589k\n"
]
}
],
"source": [
"# Get poverty headcount and rate in each year from 2023 to 2026\n",
"\n",
"costs = []\n",
"for year in range(2023, 2026):\n",
" child_poverty_baseline = (baseline.calculate(\"in_poverty\", year, map_to=\"person\")).mean()\n",
" child_poverty_reformed = (reformed.calculate(\"in_poverty\", year, map_to=\"person\")).mean()\n",
" print(f\"Baseline: {child_poverty_baseline:.1%}, reformed: {child_poverty_reformed:.1%}\")\n",
" child_poverty_baseline_hc = (baseline.calculate(\"in_poverty\", year, map_to=\"person\")).sum() / 1e3\n",
" child_poverty_reformed_hc = (reformed.calculate(\"in_poverty\", year, map_to=\"person\")).sum() / 1e3\n",
" print(f\"Baseline: {child_poverty_baseline_hc:,.0f}k, reformed: {child_poverty_reformed_hc:,.0f}k, change: {child_poverty_reformed_hc - child_poverty_baseline_hc:,.0f}k\")\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"hovertemplate": "Number of children=child3<br>Employment income=%{x}<br>value=%{y}<extra></extra>",
"legendgroup": "child3",
"line": {
"color": "#ABCEEB",
"dash": "solid"
},
"marker": {
"symbol": "circle"
},
"mode": "lines",
"name": "3 children",
"orientation": "v",
"showlegend": true,
"type": "scatter",
"x": [
0,
1000,
2000,
3000,
4000,
5000,
6000,
7000,
8000,
9000,
10000,
11000,
12000,
13000,
14000,
15000,
16000,
17000,
18000,
19000,
20000,
21000,
22000,
23000,
24000,
25000,
26000,
27000,
28000,
29000,
30000,
31000,
32000,
33000,
34000,
35000,
36000,
37000,
38000,
39000,
40000,
41000,
42000,
43000,
44000,
45000,
46000,
47000,
48000,
49000,
50000,
51000,
52000,
53000,
54000,
55000,
56000,
57000,
58000,
59000,
60000,
61000,
62000,
63000,
64000,
65000,
66000,
67000,
68000,
69000,
70000,
71000,
72000,
73000,
74000,
75000,
76000,
77000,
78000,
79000,
80000,
81000,
82000,
83000,
84000,
85000,
86000,
87000,
88000,
89000,
90000,
91000,
92000,
93000,
94000,
95000,
96000,
97000,
98000,
99000,
100000
],
"xaxis": "x",
"y": [
2934.958984375,
2934.958984375,
2934.9580078125,
2934.9599609375,
2934.958984375,
2934.958984375,
2934.958984375,
2934.958984375,
2934.9609375,
2934.9609375,
2934.9609375,
2934.9609375,
2934.958984375,
2934.958984375,
2934.9609375,
2934.958984375,
2934.958984375,
2934.9609375,
2934.958984375,
2934.9609375,
2934.958984375,
2934.9609375,
2934.9609375,
2934.958984375,
2934.9609375,
2934.958984375,
2934.9609375,
2934.9609375,
2934.958984375,
2934.9609375,
2836.21875,
2450.984375,
2065.75,
1680.51171875,
1295.27734375,
910.04296875,
524.8046875,
139.568359375,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"yaxis": "y"
},
{
"hovertemplate": "Number of children=child4<br>Employment income=%{x}<br>value=%{y}<extra></extra>",
"legendgroup": "child4",
"line": {
"color": "#49A6E2",
"dash": "solid"
},
"marker": {
"symbol": "circle"
},
"mode": "lines",
"name": "4 children",
"orientation": "v",
"showlegend": true,
"type": "scatter",
"x": [
0,
1000,
2000,
3000,
4000,
5000,
6000,
7000,
8000,
9000,
10000,
11000,
12000,
13000,
14000,
15000,
16000,
17000,
18000,
19000,
20000,
21000,
22000,
23000,
24000,
25000,
26000,
27000,
28000,
29000,
30000,
31000,
32000,
33000,
34000,
35000,
36000,
37000,
38000,
39000,
40000,
41000,
42000,
43000,
44000,
45000,
46000,
47000,
48000,
49000,
50000,
51000,
52000,
53000,
54000,
55000,
56000,
57000,
58000,
59000,
60000,
61000,
62000,
63000,
64000,
65000,
66000,
67000,
68000,
69000,
70000,
71000,
72000,
73000,
74000,
75000,
76000,
77000,
78000,
79000,
80000,
81000,
82000,
83000,
84000,
85000,
86000,
87000,
88000,
89000,
90000,
91000,
92000,
93000,
94000,
95000,
96000,
97000,
98000,
99000,
100000
],
"xaxis": "x",
"y": [
5869.9208984375,
5869.9208984375,
5869.919921875,
5869.919921875,
5869.921875,
5869.921875,
5869.921875,
5869.919921875,
5869.91796875,
5869.919921875,
5869.921875,
5869.919921875,
5869.91796875,
5869.921875,
5869.919921875,
5869.919921875,
5869.921875,
5869.919921875,
5869.91796875,
5869.91796875,
5869.921875,
5869.919921875,
5869.921875,
5869.921875,
5869.91796875,
5869.916015625,
5869.923828125,
5869.921875,
5869.919921875,
5869.919921875,
5771.1796875,
5385.939453125,
5000.705078125,
4615.46875,
4230.234375,
3845,
3459.765625,
3074.5234375,
2689.29296875,
2304.0625,
1918.8203125,
1533.5859375,
1148.3515625,
763.1171875,
377.87890625,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"yaxis": "y"
},
{
"hovertemplate": "Number of children=child5<br>Employment income=%{x}<br>value=%{y}<extra></extra>",
"legendgroup": "child5",
"line": {
"color": "#2C6496",
"dash": "solid"
},
"marker": {
"symbol": "circle"
},
"mode": "lines",
"name": "5 children",
"orientation": "v",
"showlegend": true,
"type": "scatter",
"x": [
0,
1000,
2000,
3000,
4000,
5000,
6000,
7000,
8000,
9000,
10000,
11000,
12000,
13000,
14000,
15000,
16000,
17000,
18000,
19000,
20000,
21000,
22000,
23000,
24000,
25000,
26000,
27000,
28000,
29000,
30000,
31000,
32000,
33000,
34000,
35000,
36000,
37000,
38000,
39000,
40000,
41000,
42000,
43000,
44000,
45000,
46000,
47000,
48000,
49000,
50000,
51000,
52000,
53000,
54000,
55000,
56000,
57000,
58000,
59000,
60000,
61000,
62000,
63000,
64000,
65000,
66000,
67000,
68000,
69000,
70000,
71000,
72000,
73000,
74000,
75000,
76000,
77000,
78000,
79000,
80000,
81000,
82000,
83000,
84000,
85000,
86000,
87000,
88000,
89000,
90000,
91000,
92000,
93000,
94000,
95000,
96000,
97000,
98000,
99000,
100000
],
"xaxis": "x",
"y": [
8804.8779296875,
8804.8779296875,
8804.876953125,
8804.87890625,
8804.87890625,
8804.87890625,
8804.876953125,
8804.876953125,
8804.87890625,
8804.87890625,
8804.87890625,
8804.87890625,
8804.87890625,
8804.875,
8804.876953125,
8804.880859375,
8804.876953125,
8804.876953125,
8804.876953125,
8804.875,
8804.876953125,
8804.880859375,
8804.87890625,
8804.876953125,
8804.876953125,
8804.875,
8804.880859375,
8804.880859375,
8804.880859375,
8804.876953125,
8706.13671875,
8320.900390625,
7935.666015625,
7550.4296875,
7165.1953125,
6779.9609375,
6394.7265625,
6009.484375,
5624.25390625,
5239.0234375,
4853.78125,
4468.546875,
4083.3125,
3698.078125,
3312.83984375,
2927.60546875,
2542.37109375,
2157.13671875,
1771.8984375,
1506.6171875,
1419.6171875,
1332.609375,
1245.6015625,
1158.59765625,
1071.58984375,
984.58203125,
897.578125,
810.5703125,
723.5625,
460.703125,
139.203125,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"yaxis": "y"
}
],
"layout": {
"font": {
"color": "#000",
"family": "Roboto Serif"
},
"height": 600,
"images": [
{
"sizex": 0.2,
"sizey": 0.2,
"source": "https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png",
"x": 1,
"xanchor": "right",
"xref": "paper",
"y": -0.15,
"yanchor": "bottom",
"yref": "paper"
}
],
"legend": {
"title": {
"text": "Number of children"
},
"tracegroupgap": 0
},
"margin": {
"b": 100,
"l": 100,
"r": 100,
"t": 100
},
"modebar": {
"bgcolor": "rgba(0,0,0,0)",
"color": "rgba(0,0,0,0)"
},
"template": {
"data": {
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "white",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "bar"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "white",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "barpolar"
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "#C8D4E3",
"linecolor": "#C8D4E3",
"minorgridcolor": "#C8D4E3",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "#C8D4E3",
"linecolor": "#C8D4E3",
"minorgridcolor": "#C8D4E3",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"choropleth": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "choropleth"
}
],
"contour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "contour"
}
],
"contourcarpet": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "contourcarpet"
}
],
"heatmap": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmap"
}
],
"heatmapgl": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmapgl"
}
],
"histogram": [
{
"marker": {
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "histogram"
}
],
"histogram2d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2d"
}
],
"histogram2dcontour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2dcontour"
}
],
"mesh3d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "mesh3d"
}
],
"parcoords": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "parcoords"
}
],
"pie": [
{
"automargin": true,
"type": "pie"
}
],
"scatter": [
{
"fillpattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
},
"type": "scatter"
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter3d"
}
],
"scattercarpet": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattercarpet"
}
],
"scattergeo": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergeo"
}
],
"scattergl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergl"
}
],
"scattermapbox": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermapbox"
}
],
"scatterpolar": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolar"
}
],
"scatterpolargl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolargl"
}
],
"scatterternary": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterternary"
}
],
"surface": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "surface"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
]
},
"layout": {
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"autotypenumbers": "strict",
"coloraxis": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"colorscale": {
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequential": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"sequentialminus": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
]
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"geo": {
"bgcolor": "white",
"lakecolor": "white",
"landcolor": "white",
"showlakes": true,
"showland": true,
"subunitcolor": "#C8D4E3"
},
"hoverlabel": {
"align": "left"
},
"hovermode": "closest",
"mapbox": {
"style": "light"
},
"paper_bgcolor": "white",
"plot_bgcolor": "white",
"polar": {
"angularaxis": {
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": ""
},
"bgcolor": "white",
"radialaxis": {
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": ""
}
},
"scene": {
"xaxis": {
"backgroundcolor": "white",
"gridcolor": "#DFE8F3",
"gridwidth": 2,
"linecolor": "#EBF0F8",
"showbackground": true,
"ticks": "",
"zerolinecolor": "#EBF0F8"
},
"yaxis": {
"backgroundcolor": "white",
"gridcolor": "#DFE8F3",
"gridwidth": 2,
"linecolor": "#EBF0F8",
"showbackground": true,
"ticks": "",
"zerolinecolor": "#EBF0F8"
},
"zaxis": {
"backgroundcolor": "white",
"gridcolor": "#DFE8F3",
"gridwidth": 2,
"linecolor": "#EBF0F8",
"showbackground": true,
"ticks": "",
"zerolinecolor": "#EBF0F8"
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"ternary": {
"aaxis": {
"gridcolor": "#DFE8F3",
"linecolor": "#A2B1C6",
"ticks": ""
},
"baxis": {
"gridcolor": "#DFE8F3",
"linecolor": "#A2B1C6",
"ticks": ""
},
"bgcolor": "white",
"caxis": {
"gridcolor": "#DFE8F3",
"linecolor": "#A2B1C6",
"ticks": ""
}
},
"title": {
"x": 0.05
},
"xaxis": {
"automargin": true,
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "#EBF0F8",
"zerolinewidth": 2
},
"yaxis": {
"automargin": true,
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "#EBF0F8",
"zerolinewidth": 2
}
}
},
"title": {
"text": "Impact of removing the UC child limit on net income by number of children"
},
"width": 800,
"xaxis": {
"anchor": "y",
"domain": [
0,
1
],
"title": {
"text": "Employment income"
}
},
"yaxis": {
"anchor": "x",
"domain": [
0,
1
],
"tickformat": ",.0f",
"tickprefix": "£",
"title": {
"text": "Change to net income"
}
}
}
}
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Plot gain by income and number of children\n",
"\n",
"base_situation = {\n",
" \"people\": {\n",
" \"parent\": {\n",
" \"age\": 40,\n",
" },\n",
" },\n",
" \"benunits\": {\n",
" \"benunit\": {\n",
" \"members\": [\"parent\"]\n",
" }\n",
" },\n",
" \"households\": {\n",
" \"household\": {\n",
" \"members\": [\"parent\"]\n",
" }\n",
" },\n",
" \"axes\": [[{\n",
" \"name\": \"employment_income\",\n",
" \"min\": 0,\n",
" \"max\": 100_000,\n",
" \"count\": 101,\n",
" }]]\n",
"}\n",
"import json\n",
"def create_situation(num_children: int):\n",
" situation = json.loads(json.dumps(base_situation))\n",
" for i in range(num_children):\n",
" situation[\"people\"][f\"child{i+1}\"] = {\"age\": 3}\n",
" situation[\"benunits\"][\"benunit\"][\"members\"].append(f\"child{i+1}\")\n",
" situation[\"households\"][\"household\"][\"members\"].append(f\"child{i+1}\")\n",
" return situation\n",
"\n",
"from policyengine_uk import Simulation\n",
"import pandas as pd\n",
"situations = [create_situation(i) for i in range(1, 6)]\n",
"\n",
"def get_net_income_diff(s):\n",
" baseline = Simulation(situation=s)\n",
" reformed = Simulation(situation=s, reform=reform)\n",
" return reformed.calculate(\"household_net_income\", 2023) - baseline.calculate(\"household_net_income\", 2023)\n",
"\n",
"df = pd.DataFrame()\n",
"for i in range(2, len(situations)):\n",
" df[f\"child{i+1}\"] = get_net_income_diff(situations[i])\n",
"\n",
"df[\"employment_income\"] = Simulation(situation=situations[0]).calculate(\"employment_income\", map_to=\"household\")\n",
"\n",
"import plotly.express as px\n",
"LIGHTER_BLUE = \"#ABCEEB\" # Blue 100.\n",
"LIGHT_BLUE = \"#49A6E2\" # Blue 500.\n",
"\n",
"BLUE_COLOR_SEQUENCE = [LIGHTER_BLUE, LIGHT_BLUE, \"#2C6496\"]\n",
"fig = px.line(\n",
" df, \n",
" x=\"employment_income\", \n",
" y=df.columns,\n",
" color_discrete_sequence=BLUE_COLOR_SEQUENCE,\n",
" labels=dict(\n",
" employment_income=\"Employment income\",\n",
" variable=\"Number of children\",\n",
" )\n",
" )\n",
"\n",
"# Update names of legend items to \"1 child\", \"2 children\", etc. instead of \"child1\", \"child2\", etc.\n",
"\n",
"def rename_item(name):\n",
" # child1 -> 1 child\n",
" # child2 -> 2 children\n",
"\n",
" if name.startswith(\"child\"):\n",
" num_children = int(name[5])\n",
" if num_children == 1:\n",
" return \"1 child\"\n",
" else:\n",
" return f\"{num_children} children\"\n",
" \n",
"fig.for_each_trace(lambda trace: trace.update(name=rename_item(trace.name)))\n",
"\n",
"\n",
"\n",
"def format_chart(fig):\n",
" \"\"\"\n",
" const WHITE = \"#FFF\";\n",
" const BLUE = \"#2C6496\";\n",
" const GRAY = \"#BDBDBD\";\n",
" const MEDIUM_DARK_GRAY = \"#D2D2D2\";\n",
" const DARK_GRAY = \"#616161\";\n",
" const GREEN = \"#29d40f\";\n",
" const LIGHT_GRAY = \"#F2F2F2\";\n",
" const LIGHT_GREEN = \"#C5E1A5\";\n",
" const DARK_GREEN = \"#558B2F\";\n",
" const DARK_RED = \"#b50d0d\";\n",
" const BLACK = \"#000\";\n",
" Logo at /Users/nikhil/policyengine/policyengine-app/src/images/logos/policyengine/blue.png, should be in the bottom right corner\n",
" template: plotly_white\n",
" \"\"\"\n",
" \n",
" # Add logo to bottom right corner\n",
" fig.add_layout_image(\n",
" dict(\n",
" source=\"https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png\",\n",
" xref=\"paper\",\n",
" yref=\"paper\",\n",
" x=1,\n",
" y=-0.15,\n",
" sizex=0.2,\n",
" sizey=0.2,\n",
" xanchor=\"right\",\n",
" yanchor=\"bottom\",\n",
" )\n",
" )\n",
"\n",
" # set template\n",
" fig.update_layout(\n",
" template=\"plotly_white\",\n",
" height=600,\n",
" width=800,\n",
" margin= dict(\n",
" t=100,\n",
" b=100,\n",
" l=100,\n",
" r=100,\n",
" ),\n",
" )\n",
" # don't show modebar\n",
" fig.update_layout(\n",
" modebar=dict(\n",
" bgcolor=\"rgba(0,0,0,0)\",\n",
" color=\"rgba(0,0,0,0)\",\n",
" )\n",
" )\n",
" return fig\n",
"\n",
"fig.update_layout(\n",
" width=800,\n",
" height=600,\n",
" title=\"Impact of removing the UC child limit on net income by number of children\",\n",
" template=\"plotly_white\",\n",
" yaxis_title=\"Change to net income\",\n",
" yaxis_tickformat=\",.0f\",\n",
" yaxis_tickprefix=\"£\",\n",
" xaxis_title=\"Employment income\",\n",
" # Roboto serif font, black\n",
" font=dict(\n",
" family=\"Roboto Serif\",\n",
" color=\"#000\",\n",
" ),\n",
")\n",
"\n",
"fig = format_chart(fig)\n",
"fig\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"# Plot gain by income and number of children\n",
"\n",
"base_situation = {\n",
" \"people\": {\n",
" \"parent\": {\n",
" \"age\": 40,\n",
" },\n",
" },\n",
" \"benunits\": {\n",
" \"benunit\": {\n",
" \"members\": [\"parent\"]\n",
" }\n",
" },\n",
" \"households\": {\n",
" \"household\": {\n",
" \"members\": [\"parent\"]\n",
" }\n",
" },\n",
" \"axes\": [[{\n",
" \"name\": \"employment_income\",\n",
" \"min\": 0,\n",
" \"max\": 100_000,\n",
" \"count\": 101,\n",
" }]]\n",
"}\n",
"import json\n",
"def create_situation(num_children: int):\n",
" situation = json.loads(json.dumps(base_situation))\n",
" for i in range(num_children):\n",
" situation[\"people\"][f\"child{i+1}\"] = {\"age\": 3}\n",
" situation[\"benunits\"][\"benunit\"][\"members\"].append(f\"child{i+1}\")\n",
" situation[\"households\"][\"household\"][\"members\"].append(f\"child{i+1}\")\n",
" return situation\n",
"\n",
"from policyengine_uk import Simulation\n",
"import pandas as pd\n",
"situations = [create_situation(i) for i in range(1, 6)]\n",
"\n",
"def get_(s):\n",
" baseline = Simulation(situation=s)\n",
" reformed = Simulation(situation=s, reform=reform)\n",
" return reformed.calculate(\"household_net_income\", 2023) - baseline.calculate(\"household_net_income\", 2023)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"alignmentgroup": "True",
"hovertemplate": "num_children=3<br>decile=%{x}<br>count=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "3",
"marker": {
"color": "#ABCEEB",
"pattern": {
"shape": ""
}
},
"name": "3",
"offsetgroup": "3",
"orientation": "v",
"showlegend": true,
"text": [
"80k",
"86k",
"130k",
"94k",
"105k",
"121k",
"87k",
"52k",
"87k",
"66k"
],
"textposition": "auto",
"type": "bar",
"x": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
],
"xaxis": "x",
"y": [
80483.61780166626,
86400.09322738647,
130866.47127151489,
94968.72542572021,
105062.35076904297,
121961.21054077148,
87957.60229492188,
52210.44278717041,
87230.63702392578,
66180.86834716797
],
"yaxis": "y"
},
{
"alignmentgroup": "True",
"hovertemplate": "num_children=4<br>decile=%{x}<br>count=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "4",
"marker": {
"color": "#49A6E2",
"pattern": {
"shape": ""
}
},
"name": "4",
"offsetgroup": "4",
"orientation": "v",
"showlegend": true,
"text": [
"23k",
"31k",
"40k",
"41k",
"33k",
"19k",
"15k",
"22k",
"7k",
"14k"
],
"textposition": "auto",
"type": "bar",
"x": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
],
"xaxis": "x",
"y": [
23009.477111816406,
31135.82583618164,
40260.72448730469,
41338.50733947754,
33517.653091430664,
19485.989334106445,
15136.111572265625,
22943.557861328125,
7713.412414550781,
14372.479125976562
],
"yaxis": "y"
},
{
"alignmentgroup": "True",
"hovertemplate": "num_children=5<br>decile=%{x}<br>count=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "5",
"marker": {
"color": "#2C6496",
"pattern": {
"shape": ""
}
},
"name": "5",
"offsetgroup": "5",
"orientation": "v",
"showlegend": true,
"text": [
"3k",
"9k",
"13k",
"9k",
"12k",
"4k",
"3k",
"0k",
"6k",
"3k"
],
"textposition": "auto",
"type": "bar",
"x": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
],
"xaxis": "x",
"y": [
3977.4896240234375,
9822.167663574219,
13831.685241699219,
9455.550567626953,
12531.163879394531,
4993.8795166015625,
3081.5703125,
0,
6795.978759765625,
3260.855224609375
],
"yaxis": "y"
},
{
"alignmentgroup": "True",
"hovertemplate": "num_children=6<br>decile=%{x}<br>count=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "6",
"marker": {
"color": "#ABCEEB",
"pattern": {
"shape": ""
}
},
"name": "6",
"offsetgroup": "6",
"orientation": "v",
"showlegend": true,
"text": [
"0k",
"3k",
"0k",
"2k",
"6k",
"4k",
"0k",
"0k",
"0k",
"0k"
],
"textposition": "auto",
"type": "bar",
"x": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
],
"xaxis": "x",
"y": [
0,
3981.643768310547,
762.18310546875,
2731.454833984375,
6916.4921875,
4707.44921875,
0,
0,
0,
0
],
"yaxis": "y"
}
],
"layout": {
"barmode": "stack",
"font": {
"color": "#000",
"family": "Roboto Serif"
},
"height": 600,
"images": [
{
"sizex": 0.2,
"sizey": 0.2,
"source": "https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png",
"x": 1,
"xanchor": "right",
"xref": "paper",
"y": -0.15,
"yanchor": "bottom",
"yref": "paper"
}
],
"legend": {
"title": {
"text": "Number of children"
},
"tracegroupgap": 0
},
"margin": {
"b": 100,
"l": 100,
"r": 100,
"t": 100
},
"modebar": {
"bgcolor": "rgba(0,0,0,0)",
"color": "rgba(0,0,0,0)"
},
"template": {
"data": {
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "white",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "bar"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "white",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "barpolar"
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "#C8D4E3",
"linecolor": "#C8D4E3",
"minorgridcolor": "#C8D4E3",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "#C8D4E3",
"linecolor": "#C8D4E3",
"minorgridcolor": "#C8D4E3",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"choropleth": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "choropleth"
}
],
"contour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "contour"
}
],
"contourcarpet": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "contourcarpet"
}
],
"heatmap": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmap"
}
],
"heatmapgl": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmapgl"
}
],
"histogram": [
{
"marker": {
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "histogram"
}
],
"histogram2d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2d"
}
],
"histogram2dcontour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2dcontour"
}
],
"mesh3d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "mesh3d"
}
],
"parcoords": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "parcoords"
}
],
"pie": [
{
"automargin": true,
"type": "pie"
}
],
"scatter": [
{
"fillpattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
},
"type": "scatter"
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter3d"
}
],
"scattercarpet": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattercarpet"
}
],
"scattergeo": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergeo"
}
],
"scattergl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergl"
}
],
"scattermapbox": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermapbox"
}
],
"scatterpolar": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolar"
}
],
"scatterpolargl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolargl"
}
],
"scatterternary": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterternary"
}
],
"surface": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "surface"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
]
},
"layout": {
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"autotypenumbers": "strict",
"coloraxis": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"colorscale": {
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequential": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"sequentialminus": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
]
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"geo": {
"bgcolor": "white",
"lakecolor": "white",
"landcolor": "white",
"showlakes": true,
"showland": true,
"subunitcolor": "#C8D4E3"
},
"hoverlabel": {
"align": "left"
},
"hovermode": "closest",
"mapbox": {
"style": "light"
},
"paper_bgcolor": "white",
"plot_bgcolor": "white",
"polar": {
"angularaxis": {
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": ""
},
"bgcolor": "white",
"radialaxis": {
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": ""
}
},
"scene": {
"xaxis": {
"backgroundcolor": "white",
"gridcolor": "#DFE8F3",
"gridwidth": 2,
"linecolor": "#EBF0F8",
"showbackground": true,
"ticks": "",
"zerolinecolor": "#EBF0F8"
},
"yaxis": {
"backgroundcolor": "white",
"gridcolor": "#DFE8F3",
"gridwidth": 2,
"linecolor": "#EBF0F8",
"showbackground": true,
"ticks": "",
"zerolinecolor": "#EBF0F8"
},
"zaxis": {
"backgroundcolor": "white",
"gridcolor": "#DFE8F3",
"gridwidth": 2,
"linecolor": "#EBF0F8",
"showbackground": true,
"ticks": "",
"zerolinecolor": "#EBF0F8"
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"ternary": {
"aaxis": {
"gridcolor": "#DFE8F3",
"linecolor": "#A2B1C6",
"ticks": ""
},
"baxis": {
"gridcolor": "#DFE8F3",
"linecolor": "#A2B1C6",
"ticks": ""
},
"bgcolor": "white",
"caxis": {
"gridcolor": "#DFE8F3",
"linecolor": "#A2B1C6",
"ticks": ""
}
},
"title": {
"x": 0.05
},
"xaxis": {
"automargin": true,
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "#EBF0F8",
"zerolinewidth": 2
},
"yaxis": {
"automargin": true,
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "#EBF0F8",
"zerolinewidth": 2
}
}
},
"title": {
"text": "Households by child count and income decile"
},
"uniformtext": {
"minsize": 8,
"mode": "hide"
},
"width": 800,
"xaxis": {
"anchor": "y",
"domain": [
0,
1
],
"tickvals": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
],
"title": {
"text": "Income decile"
}
},
"yaxis": {
"anchor": "x",
"domain": [
0,
1
],
"tickformat": ",.0f",
"title": {
"text": "Number of households"
}
}
}
}
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"decile = baseline.calculate(\"household_income_decile\", 2023, map_to=\"household\")\n",
"\n",
"# For each decile, give the number of households with 1, 2, 3, 4, 5, 6+ children\n",
"\n",
"df = pd.DataFrame()\n",
"for i in range(1, 11):\n",
" for num_children in range(3, 7):\n",
" row = {\n",
" \"decile\": i,\n",
" \"num_children\": int(num_children),\n",
" \"count\": ((decile == i) * (baseline.calculate(\"is_child\", map_to=\"household\") == num_children)).sum(),\n",
" }\n",
" df = df.append(row, ignore_index=True)\n",
"\n",
"df.decile = df.decile.astype(int)\n",
"df.num_children = df.num_children.astype(int).astype(str)\n",
"df[\"text\"] = [f\"{int(x / 1e3)}k\" for x in df[\"count\"]]\n",
"import plotly.express as px\n",
"\n",
"fig = px.bar(\n",
" df,\n",
" x=\"decile\",\n",
" y=\"count\",\n",
" color=\"num_children\",\n",
" color_discrete_sequence=BLUE_COLOR_SEQUENCE,\n",
" barmode=\"stack\",\n",
" text=\"text\",\n",
")\n",
"\n",
"fig = format_chart(fig)\n",
"fig.update_layout(\n",
" title=\"Households by child count and income decile\",\n",
" xaxis_title=\"Income decile\",\n",
" yaxis_title=\"Number of households\",\n",
" legend_title=\"Number of children\",\n",
" yaxis_tickformat=\",.0f\",\n",
" xaxis_tickvals=list(range(1, 11)),\n",
" font=dict(\n",
" family=\"Roboto Serif\",\n",
" color=\"#000\",\n",
" ),\n",
" # only show text where it fits\n",
" uniformtext_minsize=8,\n",
" uniformtext_mode=\"hide\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"# Replicate the Fabian Society proposal to remove only for families not expected to work.\n",
"\n",
"from policyengine_uk import Microsimulation\n",
"from policyengine_core.reforms import Reform\n",
"from policyengine_core.periods import instant\n",
"import pandas as pd\n",
"from policyengine_uk.model_api import *\n",
"\n",
"\n",
"def modify_parameters(parameters):\n",
" parameters.gov.dwp.universal_credit.elements.child.limit.child_count.update(start=instant(\"2023-01-01\"), stop=instant(\"2028-12-31\"), value=99)\n",
" return parameters\n",
"\n",
"\n",
"class UC_individual_child_element(Variable):\n",
" value_type = float\n",
" entity = Person\n",
" label = \"Universal Credit child element\"\n",
" documentation = \"For this child, given Universal Credit eligibility\"\n",
" definition_period = YEAR\n",
" unit = GBP\n",
"\n",
" def formula(person, period, parameters):\n",
" UC = parameters(period).gov.dwp.universal_credit\n",
" child_index = person(\"child_index\", period)\n",
" born_before_limit = person(\"is_child_born_before_child_limit\", period)\n",
" # New code\n",
" is_adult = person(\"is_adult\", period)\n",
" has_earnings = person(\"employment_income\", period) + person(\"self_employment_income\", period) > 0\n",
" is_disabled = person(\"is_disabled_for_benefits\", period)\n",
" age = person(\"age\", period)\n",
" is_carer_for_2_year_old = person.benunit.any(\n",
" age <= 2\n",
" )\n",
" is_ineligible_for_two_child_limit_repeal = ~person.benunit.any(is_adult * (is_disabled | is_carer_for_2_year_old | has_earnings))\n",
" child_limit_applying = where(\n",
" ~born_before_limit, UC.elements.child.limit.child_count, inf\n",
" )\n",
" child_limit_applying = where(\n",
" is_ineligible_for_two_child_limit_repeal * ~born_before_limit,\n",
" 2,\n",
" child_limit_applying,\n",
" )\n",
" # End of new code\n",
" is_eligible = (child_index != -1) & (\n",
" child_index <= child_limit_applying\n",
" )\n",
" return (\n",
" select(\n",
" [\n",
" (child_index == 1) & born_before_limit & is_eligible,\n",
" is_eligible,\n",
" ],\n",
" [\n",
" UC.elements.child.first.higher_amount,\n",
" UC.elements.child.amount,\n",
" ],\n",
" default=0,\n",
" )\n",
" * MONTHS_IN_YEAR\n",
" )\n",
"class reform(Reform):\n",
" def apply(self):\n",
" self.modify_parameters(modify_parameters)\n",
" self.update_variable(UC_individual_child_element)\n",
"\n",
"\n",
"baseline = Microsimulation()\n",
"reformed = Microsimulation(reform=reform)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"303484.4331665039"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"baseline.calculate(\"uc_child_limit_affected\", 2023, map_to=\"household\").sum()"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.3417130061645508"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Households affected by the policy\n",
"\n",
"gain = reformed.calculate(\"household_net_income\", 2023) - baseline.calculate(\"household_net_income\", 2023)\n",
"\n",
"(gain > 0).sum()/1e6"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"from policyengine_uk import Microsimulation\n",
"\n",
"baseline = Microsimulation()\n",
"baseline.default_calculation_period = 2023\n",
"income_decile = baseline.calculate(\"household_income_decile\")"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [],
"source": [
"from policyengine_uk import Microsimulation\n",
"from policyengine_core.reforms import Reform\n",
"from policyengine_core.periods import instant\n",
"import pandas as pd\n",
"\n",
"\n",
"def modify_parameters(parameters):\n",
" parameters.gov.dwp.universal_credit.elements.child.limit.child_count.update(start=instant(\"2023-01-01\"), stop=instant(\"2028-12-31\"), value=99)\n",
" parameters.gov.dwp.tax_credits.child_tax_credit.limit.child_count.update(start=instant(\"2023-01-01\"), stop=instant(\"2028-12-31\"), value=99) \n",
" parameters.gov.hmrc.income_tax.rates.uk[1].rate.update(start=instant(\"2023-01-01\"), stop=instant(\"2028-12-31\"), value=0.41)\n",
" return parameters\n",
"\n",
"\n",
"class reform(Reform):\n",
" def apply(self):\n",
" self.modify_parameters(modify_parameters)\n",
"\n",
"\n",
"baseline = Microsimulation()\n",
"reformed = Microsimulation(reform=reform)\n"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.47121670880164856"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Net cost\n",
"\n",
"reformed.calculate(\"household_net_income\", 2023).sum()/1e9 - baseline.calculate(\"household_net_income\", 2023).sum()/1e9"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"alignmentgroup": "True",
"hovertemplate": "variable=0<br>index=%{x}<br>value=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "0",
"marker": {
"color": [
"#616161",
"#2C6496",
"#2C6496",
"#2C6496",
"#2C6496",
"#2C6496",
"#2C6496",
"#2C6496",
"#616161",
"#616161",
"#616161"
],
"pattern": {
"shape": ""
}
},
"name": "0",
"offsetgroup": "0",
"orientation": "v",
"showlegend": true,
"text": [
"+nan%",
"+0.4%",
"+0.4%",
"+0.5%",
"+0.3%",
"+0.3%",
"+0.1%",
"+0.0%",
"-0.1%",
"-0.1%",
"-0.4%"
],
"textposition": "auto",
"type": "bar",
"x": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
],
"xaxis": "x",
"y": [
null,
0.00361434546222419,
0.003782002572484647,
0.004544131033548688,
0.0034740161670654655,
0.0028949295991501428,
0.0012687263808477361,
0.00007297958651920845,
-0.000634573995180701,
-0.0013579721286061872,
-0.0035826865535485246
],
"yaxis": "y"
}
],
"layout": {
"barmode": "relative",
"font": {
"color": "#000",
"family": "Roboto Serif"
},
"height": 600,
"images": [
{
"sizex": 0.2,
"sizey": 0.2,
"source": "https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png",
"x": 1,
"xanchor": "right",
"xref": "paper",
"y": -0.15,
"yanchor": "bottom",
"yref": "paper"
}
],
"legend": {
"title": {
"text": "variable"
},
"tracegroupgap": 0
},
"margin": {
"b": 100,
"l": 100,
"r": 100,
"t": 100
},
"modebar": {
"bgcolor": "rgba(0,0,0,0)",
"color": "rgba(0,0,0,0)"
},
"showlegend": false,
"template": {
"data": {
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "white",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "bar"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "white",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "barpolar"
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "#C8D4E3",
"linecolor": "#C8D4E3",
"minorgridcolor": "#C8D4E3",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "#C8D4E3",
"linecolor": "#C8D4E3",
"minorgridcolor": "#C8D4E3",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"choropleth": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "choropleth"
}
],
"contour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "contour"
}
],
"contourcarpet": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "contourcarpet"
}
],
"heatmap": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmap"
}
],
"heatmapgl": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmapgl"
}
],
"histogram": [
{
"marker": {
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "histogram"
}
],
"histogram2d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2d"
}
],
"histogram2dcontour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2dcontour"
}
],
"mesh3d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "mesh3d"
}
],
"parcoords": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "parcoords"
}
],
"pie": [
{
"automargin": true,
"type": "pie"
}
],
"scatter": [
{
"fillpattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
},
"type": "scatter"
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter3d"
}
],
"scattercarpet": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattercarpet"
}
],
"scattergeo": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergeo"
}
],
"scattergl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergl"
}
],
"scattermapbox": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermapbox"
}
],
"scatterpolar": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolar"
}
],
"scatterpolargl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolargl"
}
],
"scatterternary": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterternary"
}
],
"surface": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "surface"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
]
},
"layout": {
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"autotypenumbers": "strict",
"coloraxis": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"colorscale": {
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequential": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"sequentialminus": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
]
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"geo": {
"bgcolor": "white",
"lakecolor": "white",
"landcolor": "white",
"showlakes": true,
"showland": true,
"subunitcolor": "#C8D4E3"
},
"hoverlabel": {
"align": "left"
},
"hovermode": "closest",
"mapbox": {
"style": "light"
},
"paper_bgcolor": "white",
"plot_bgcolor": "white",
"polar": {
"angularaxis": {
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": ""
},
"bgcolor": "white",
"radialaxis": {
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": ""
}
},
"scene": {
"xaxis": {
"backgroundcolor": "white",
"gridcolor": "#DFE8F3",
"gridwidth": 2,
"linecolor": "#EBF0F8",
"showbackground": true,
"ticks": "",
"zerolinecolor": "#EBF0F8"
},
"yaxis": {
"backgroundcolor": "white",
"gridcolor": "#DFE8F3",
"gridwidth": 2,
"linecolor": "#EBF0F8",
"showbackground": true,
"ticks": "",
"zerolinecolor": "#EBF0F8"
},
"zaxis": {
"backgroundcolor": "white",
"gridcolor": "#DFE8F3",
"gridwidth": 2,
"linecolor": "#EBF0F8",
"showbackground": true,
"ticks": "",
"zerolinecolor": "#EBF0F8"
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"ternary": {
"aaxis": {
"gridcolor": "#DFE8F3",
"linecolor": "#A2B1C6",
"ticks": ""
},
"baxis": {
"gridcolor": "#DFE8F3",
"linecolor": "#A2B1C6",
"ticks": ""
},
"bgcolor": "white",
"caxis": {
"gridcolor": "#DFE8F3",
"linecolor": "#A2B1C6",
"ticks": ""
}
},
"title": {
"x": 0.05
},
"xaxis": {
"automargin": true,
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "#EBF0F8",
"zerolinewidth": 2
},
"yaxis": {
"automargin": true,
"gridcolor": "#EBF0F8",
"linecolor": "#EBF0F8",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "#EBF0F8",
"zerolinewidth": 2
}
}
},
"title": {
"text": "Impact of removing the two-child limit and increasing the higher rate by 1p <br>by income decile"
},
"uniformtext": {
"minsize": 8,
"mode": "hide"
},
"width": 800,
"xaxis": {
"anchor": "y",
"domain": [
0,
1
],
"tickvals": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
],
"title": {
"text": "Income decile"
}
},
"yaxis": {
"anchor": "x",
"domain": [
0,
1
],
"tickformat": "+,.1%",
"title": {
"text": "Relative change to net income"
}
}
}
}
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"income_decile = baseline.calculate(\"household_income_decile\")\n",
"gain = reformed.calculate(\"household_net_income\") - baseline.calculate(\"household_net_income\")\n",
"income = baseline.calculate(\"household_net_income\")\n",
"values = gain.groupby(income_decile).sum() / income.groupby(income_decile).sum()\n",
"text = [f\"{x:+.1%}\" for x in values]\n",
"fig = px.bar(values, text=text)\n",
"DARK_GRAY = \"#616161\"\n",
"BLUE = \"#2C6496\"\n",
"fig = format_chart(fig)\n",
"\n",
"# bars should be blue if positive, red if negative\n",
"fig.update_traces(\n",
" marker_color=[\n",
" BLUE if x > 0 else DARK_GRAY for x in fig.data[0].y\n",
" ]\n",
")\n",
"fig.update_layout(\n",
" title=\"Impact of removing the two-child limit and increasing the higher rate by 1p <br>by income decile\",\n",
" yaxis=dict(\n",
" title=\"Relative change to net income\",\n",
" tickformat=\"+,.1%\",\n",
" ),\n",
" xaxis=dict(\n",
" title=\"Income decile\",\n",
" tickvals=list(range(1, 11)),\n",
" ),\n",
" showlegend=False,\n",
" font=dict(\n",
" family=\"Roboto Serif\",\n",
" color=\"#000\",\n",
" ),\n",
" uniformtext_minsize=8,\n",
" uniformtext_mode=\"hide\",\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment