diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb..e6e21caa3 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: minor + changes: + added: + - Pension Credit documentation page. diff --git a/docs/book/_toc.yml b/docs/book/_toc.yml index e5e3d030f..5ae58a4c7 100644 --- a/docs/book/_toc.yml +++ b/docs/book/_toc.yml @@ -10,6 +10,7 @@ parts: chapters: - file: programs/gov/hmrc/child-benefit - file: programs/gov/dwp/universal-credit + - file: programs/gov/dwp/pension-credit - file: programs/gov/hmrc/national-insurance - file: programs/gov/hmrc/fuel-duty - file: programs/gov/hmrc/stamp-duty diff --git a/docs/book/examples/income-sources.ipynb b/docs/book/examples/income-sources.ipynb index 335a94e33..dbee5203d 100644 --- a/docs/book/examples/income-sources.ipynb +++ b/docs/book/examples/income-sources.ipynb @@ -1152,15 +1152,25 @@ "\n", "sim = Microsimulation()\n", "\n", - "is_pensioner_household = (sim.calculate(\"is_SP_age\", map_to=\"household\") > 0) * (sim.calculate(\"is_child\", map_to=\"household\") == 0)\n", + "is_pensioner_household = (\n", + " sim.calculate(\"is_SP_age\", map_to=\"household\") > 0\n", + ") * (sim.calculate(\"is_child\", map_to=\"household\") == 0)\n", "household_benefits = sim.calculate(\"household_benefits\")\n", "household_pensions = sim.calculate(\"pension_income\", map_to=\"household\")\n", - "household_investment_income = sim.calculate(\"capital_income\", map_to=\"household\")\n", - "household_earnings = sim.calculate(\"employment_income\", map_to=\"household\") + sim.calculate(\"self_employment_income\", map_to=\"household\")\n", + "household_investment_income = sim.calculate(\n", + " \"capital_income\", map_to=\"household\"\n", + ")\n", + "household_earnings = sim.calculate(\n", + " \"employment_income\", map_to=\"household\"\n", + ") + sim.calculate(\"self_employment_income\", map_to=\"household\")\n", "total_income = sim.calculate(\"household_market_income\") + household_benefits\n", "\n", - "equivalised_income = sim.calculate(\"equiv_household_net_income\")[is_pensioner_household]\n", - "household_count_people = sim.calculate(\"people\", map_to=\"household\")[is_pensioner_household]\n", + "equivalised_income = sim.calculate(\"equiv_household_net_income\")[\n", + " is_pensioner_household\n", + "]\n", + "household_count_people = sim.calculate(\"people\", map_to=\"household\")[\n", + " is_pensioner_household\n", + "]\n", "equivalised_income.weights *= household_count_people.values\n", "household_income_decile = equivalised_income.decile_rank()\n", "\n", @@ -1183,22 +1193,34 @@ " income_sources.append(income_source)\n", " income_source_values = income_source_decodes[income_source]\n", " values.append(\n", - " income_source_values[is_pensioner_household][in_decile].sum() / total_income[is_pensioner_household][in_decile].sum()\n", + " income_source_values[is_pensioner_household][in_decile].sum()\n", + " / total_income[is_pensioner_household][in_decile].sum()\n", " )\n", - " cumulative_income += income_source_values[is_pensioner_household][in_decile].sum()\n", + " cumulative_income += income_source_values[is_pensioner_household][\n", + " in_decile\n", + " ].sum()\n", " # Add 'other income'\n", " deciles.append(decile)\n", " income_sources.append(\"Other\")\n", - " values.append(1 - cumulative_income / total_income[is_pensioner_household][in_decile].sum())\n", + " values.append(\n", + " 1\n", + " - cumulative_income\n", + " / total_income[is_pensioner_household][in_decile].sum()\n", + " )\n", "\n", - "df = pd.DataFrame({\n", - " \"Decile\": deciles,\n", - " \"Income source\": income_sources,\n", - " \"Value\": values,\n", - "})\n", + "df = pd.DataFrame(\n", + " {\n", + " \"Decile\": deciles,\n", + " \"Income source\": income_sources,\n", + " \"Value\": values,\n", + " }\n", + ")\n", "\n", "# Order by state support, other income, pensions, investment, earnings\n", - "df[\"Income source\"] = pd.Categorical(df[\"Income source\"], [\"State support\", \"Other\", \"Pensions\", \"Investment\", \"Earnings\"])\n", + "df[\"Income source\"] = pd.Categorical(\n", + " df[\"Income source\"],\n", + " [\"State support\", \"Other\", \"Pensions\", \"Investment\", \"Earnings\"],\n", + ")\n", "df = df.sort_values([\"Decile\", \"Income source\"], ascending=[True, False])\n", "\n", "import plotly.express as px\n", @@ -1217,7 +1239,7 @@ " yaxis=dict(\n", " tickformat=\".0%\",\n", " title=\"Percentage of income\",\n", - " tickvals=[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, .7, .8, .9, 1],\n", + " tickvals=[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],\n", " ),\n", " xaxis=dict(\n", " title=\"Income decile\",\n", @@ -1228,7 +1250,7 @@ "fig = format_fig(fig).update_layout(\n", " title=\"Sources of income for pensioner households\",\n", ")\n", - "fig\n" + "fig" ] } ], diff --git a/docs/book/programs/gov/dcms/bbc/tv-licence.ipynb b/docs/book/programs/gov/dcms/bbc/tv-licence.ipynb index 2e2eb93cc..4eed2eaad 100644 --- a/docs/book/programs/gov/dcms/bbc/tv-licence.ipynb +++ b/docs/book/programs/gov/dcms/bbc/tv-licence.ipynb @@ -127,16 +127,19 @@ "dcms = system.parameters.gov.dcms\n", "\n", "df = pd.DataFrame()\n", - "df['Date'] = [\n", - " parameter.instant_str for parameter in dcms.bbc.tv_licence.colour.values_list\n", + "df[\"Date\"] = [\n", + " parameter.instant_str\n", + " for parameter in dcms.bbc.tv_licence.colour.values_list\n", "]\n", - "df['Full TV Licence Fee'] = [\n", - " f'£{parameter.value:.2f}' for parameter in dcms.bbc.tv_licence.colour.values_list\n", + "df[\"Full TV Licence Fee\"] = [\n", + " f\"£{parameter.value:.2f}\"\n", + " for parameter in dcms.bbc.tv_licence.colour.values_list\n", "]\n", - "df['Blind TV Licence Fee'] = [\n", - " f'£{0.5 * parameter.value:.2f}' for parameter in dcms.bbc.tv_licence.colour.values_list\n", + "df[\"Blind TV Licence Fee\"] = [\n", + " f\"£{0.5 * parameter.value:.2f}\"\n", + " for parameter in dcms.bbc.tv_licence.colour.values_list\n", "]\n", - "df.sort_values('Date').set_index('Date')" + "df.sort_values(\"Date\").set_index(\"Date\")" ] }, { @@ -311,24 +314,29 @@ ], "source": [ "import pandas as pd\n", + "\n", "# aged discount\n", "aged_discount = {\n", " \"Reformed value\": [0, 0.25, 0.50, 0.75],\n", " \"Current value\": [],\n", " \"Change against current\": [],\n", " \"Tax revenues impact (£m)\": [91.7, 68.8, 45.9, 22.9],\n", - " \"Reference\": []\n", + " \"Reference\": [],\n", "}\n", "reference_list_ad = [\n", " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27903®ion=uk&timePeriod=2023&baseline=1\",\n", " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27083®ion=uk&timePeriod=2023&baseline=1\",\n", " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=19090®ion=uk&timePeriod=2023&baseline=1\",\n", - " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27909®ion=uk&timePeriod=2023&baseline=1\"\n", + " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27909®ion=uk&timePeriod=2023&baseline=1\",\n", "]\n", "for i in range(len(aged_discount[\"Reformed value\"])):\n", " aged_discount[\"Current value\"] += [\"100%\"]\n", - " aged_discount[\"Change against current\"] += [f\"{aged_discount['Reformed value'][i]-1:.0%}\"]\n", - " aged_discount[\"Reformed value\"][i] = f\"{aged_discount['Reformed value'][i]:.0%}\"\n", + " aged_discount[\"Change against current\"] += [\n", + " f\"{aged_discount['Reformed value'][i]-1:.0%}\"\n", + " ]\n", + " aged_discount[\"Reformed value\"][\n", + " i\n", + " ] = f\"{aged_discount['Reformed value'][i]:.0%}\"\n", " aged_discount[\"Reference\"] += [\n", " f\"Budgetary impact of changing aged discount to {aged_discount['Reformed value'][i]}\"\n", " ]\n", @@ -337,14 +345,25 @@ "df_aged_discount[\"Reformed policy\"] = \"Aged discount\"\n", "\n", "# minimum age\n", - "age_list = list(range(70,81))\n", + "age_list = list(range(70, 81))\n", "age_list.remove(75)\n", "min_age = {\n", " \"Reformed value\": age_list,\n", " \"Current value\": [],\n", " \"Change against current\": [],\n", - " \"Tax revenues impact (£m)\": [-19.6, -11.4, -7.7, -2.4, -1.5, 1.3, 2.2, 3.7, 7.1, 91.7],\n", - " \"Reference\": []\n", + " \"Tax revenues impact (£m)\": [\n", + " -19.6,\n", + " -11.4,\n", + " -7.7,\n", + " -2.4,\n", + " -1.5,\n", + " 1.3,\n", + " 2.2,\n", + " 3.7,\n", + " 7.1,\n", + " 91.7,\n", + " ],\n", + " \"Reference\": [],\n", "}\n", "reference_list_minage = [\n", " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27932®ion=uk&timePeriod=2023&baseline=1\",\n", @@ -356,13 +375,13 @@ " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27951®ion=uk&timePeriod=2023&baseline=1\",\n", " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27953®ion=uk&timePeriod=2023&baseline=1\",\n", " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27955®ion=uk&timePeriod=2023&baseline=1\",\n", - " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27960®ion=uk&timePeriod=2023&baseline=1\"\n", + " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27960®ion=uk&timePeriod=2023&baseline=1\",\n", "]\n", "for i in range(len(min_age[\"Reformed value\"])):\n", " min_age[\"Current value\"] += [75]\n", " min_age[\"Change against current\"] += [min_age[\"Reformed value\"][i] - 75]\n", " min_age[\"Reference\"] += [\n", - " f\"Budgetary impact of changing minimum age for aged discount to {age_list[i]}\"\n", + " f'Budgetary impact of changing minimum age for aged discount to {age_list[i]}'\n", " ]\n", "\n", "df_min_age = pd.DataFrame(min_age)\n", @@ -372,32 +391,36 @@ "fee_list = list(range(157, 162))\n", "fee_list.remove(159)\n", "licence_fee = {\n", - " \"Reformed value\": fee_list,\n", - " \"Current value\": [],\n", - " \"Change against current\": [],\n", - " \"Tax revenues impact (£m)\": [-52.1, -26, 26, 52.1],\n", - " \"Reference\": []\n", + " \"Reformed value\": fee_list,\n", + " \"Current value\": [],\n", + " \"Change against current\": [],\n", + " \"Tax revenues impact (£m)\": [-52.1, -26, 26, 52.1],\n", + " \"Reference\": [],\n", "}\n", "reference_list_fee = [\n", " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27089®ion=uk&timePeriod=2023&baseline=1\",\n", " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=27087®ion=uk&timePeriod=2023&baseline=1\",\n", " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=26981®ion=uk&timePeriod=2023&baseline=1\",\n", - " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=26983®ion=uk&timePeriod=2023&baseline=1\"\n", + " \"https://policyengine.org/uk/policy?focus=policyOutput.netIncome&reform=26983®ion=uk&timePeriod=2023&baseline=1\",\n", "]\n", "for i in range(len(licence_fee[\"Reformed value\"])):\n", " licence_fee[\"Current value\"] += [\"£159\"]\n", - " licence_fee[\"Change against current\"] += [f\"£{licence_fee['Reformed value'][i]-159}\"]\n", + " licence_fee[\"Change against current\"] += [\n", + " f\"£{licence_fee['Reformed value'][i]-159}\"\n", + " ]\n", " licence_fee[\"Reformed value\"][i] = f\"£{licence_fee['Reformed value'][i]}\"\n", " licence_fee[\"Reference\"] += [\n", " f\"Budgetary impact of changing licence fee to {licence_fee['Reformed value'][i]}\"\n", " ]\n", "\n", - "df_licence_fee =pd.DataFrame(licence_fee)\n", + "df_licence_fee = pd.DataFrame(licence_fee)\n", "df_licence_fee[\"Reformed policy\"] = \"TV licence fee\"\n", "\n", "# concat df\n", "df_reform = pd.concat([df_aged_discount, df_min_age, df_licence_fee])\n", - "df_reform.set_index([\"Reformed policy\", \"Current value\", \"Reformed value\"]).style.format(lambda x: x)\n" + "df_reform.set_index(\n", + " [\"Reformed policy\", \"Current value\", \"Reformed value\"]\n", + ").style.format(lambda x: x)" ] } ], diff --git a/docs/book/programs/gov/dwp/pension-credit.ipynb b/docs/book/programs/gov/dwp/pension-credit.ipynb new file mode 100644 index 000000000..d88ca5aa4 --- /dev/null +++ b/docs/book/programs/gov/dwp/pension-credit.ipynb @@ -0,0 +1,2603 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8d07409a", + "metadata": {}, + "source": [ + "# Pension Credit\n", + "\n", + "Pension Credit is a means-tested benefit payment administered by the Department for Work and Pensions (DWP) in the United Kingdom. It was introduced to provide financial assistance to pensioners and ensure they have a minimum income level. Pension Credit combines two main elements: Guarantee Credit and Savings Credit.\n", + "\n", + "* Guarantee Credit: Intended for pensioners who have reached the qualifying age and have a low income. It tops up \n", + " their weekly income to a guaranteed minimum level, which varies based on individual circumstances.\n", + "* Savings Credit: Designed for pensioners who have saved for their retirement or have a modest income. It provides \n", + " additional support to those who have some savings or a second pension.\n", + "\n", + "\n", + "Pension Credit parameters can be found in `policyengine_uk/parameters/gov/dwp/pension_credit` and logic in `policyengine_uk/variables/dwp/pension_credit.py`.\n", + "\n", + "## Legislation\n", + "\n", + "The legal framework for Guarantee Credit is primarily defined in the legislation provided on the [The State Pension Credit Regulations 2002](https://www.legislation.gov.uk/uksi/2002/1792/regulation/6) legislation website. \n", + "The legal framework for Savings Credit is primarily defined in the legislation provided on the [State Pension Credit Act 2002](https://www.legislation.gov.uk/ukpga/2002/16/section/3) legislation website. \n", + "\n", + "## Pension Credit Rate Changes\n", + "\n", + "Some key components of Guarantee Credit include:\n", + "\n", + "* Additional Minimum Guarantee\n", + "* Carer addition\n", + "* Child-related addition\n", + "* Disabled-child minimum guarantee\n", + "* Severe disabled-child minimum guarantee\n", + "* Severe disabled-adult minimum guarantee\n", + "\n", + "\n", + "The table below shows some of the rates covered by PolicyEngine-UK. " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "dbb3de6d", + "metadata": { + "scrolled": true, + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
elementCarerChildDisabled childSevere disabled adultSevere disabled child
date
2019-01-0129.0264.30
2020-01-0136.053.3429.0265.8588.34
2021-01-0137.554.3229.5266.9592.12
2022-01-0137.754.629.6667.3092.54
2023-01-0138.8556.3530.5869.4095.48
2024-01-0138.8556.3530.5869.4095.48
\n", + "
" + ], + "text/plain": [ + "element Carer Child Disabled child Severe disabled adult \\\n", + "date \n", + "2019-01-01 29.02 64.30 \n", + "2020-01-01 36.0 53.34 29.02 65.85 \n", + "2021-01-01 37.5 54.32 29.52 66.95 \n", + "2022-01-01 37.7 54.6 29.66 67.30 \n", + "2023-01-01 38.85 56.35 30.58 69.40 \n", + "2024-01-01 38.85 56.35 30.58 69.40 \n", + "\n", + "element Severe disabled child \n", + "date \n", + "2019-01-01 \n", + "2020-01-01 88.34 \n", + "2021-01-01 92.12 \n", + "2022-01-01 92.54 \n", + "2023-01-01 95.48 \n", + "2024-01-01 95.48 " + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from policyengine_uk.system import system\n", + "\n", + "parameters = system.parameters\n", + "\n", + "carer_addition = (\n", + " parameters.gov.dwp.pension_credit.guarantee_credit.carer.addition\n", + ")\n", + "child_addition = (\n", + " parameters.gov.dwp.pension_credit.guarantee_credit.child.addition\n", + ")\n", + "disabled_child = (\n", + " parameters.gov.dwp.pension_credit.guarantee_credit.child.disability.addition\n", + ")\n", + "severe_disabled_child = (\n", + " parameters.gov.dwp.pension_credit.guarantee_credit.child.disability.severe.addition\n", + ")\n", + "severe_disabled = (\n", + " parameters.gov.dwp.pension_credit.guarantee_credit.severe_disability.addition\n", + ")\n", + "\n", + "\n", + "elements = [\n", + " carer_addition,\n", + " child_addition,\n", + " disabled_child,\n", + " severe_disabled_child,\n", + " severe_disabled,\n", + "] # [...]\n", + "\n", + "dates = [\n", + " \"2019-01-01\",\n", + " \"2020-01-01\",\n", + " \"2021-01-01\",\n", + " \"2022-01-01\",\n", + " \"2023-01-01\",\n", + " \"2024-01-01\",\n", + "]\n", + "names = [\n", + " \"Carer\",\n", + " \"Child\",\n", + " \"Disabled child\",\n", + " \"Severe disabled child\",\n", + " \"Severe disabled adult\",\n", + "]\n", + "\n", + "import pandas as pd\n", + "\n", + "df = pd.DataFrame()\n", + "\n", + "for date in dates:\n", + " for element, name in zip(elements, names):\n", + " # Append to a dataframe: row = date, column = element, value = amount\n", + " new_row = {\"date\": date, \"element\": name, \"amount\": element(date)}\n", + " # Append row to the dataframe\n", + " df = pd.concat([df, pd.DataFrame([new_row])])\n", + "\n", + "\n", + "# merge element cells\n", + "pivot_df = df.pivot(index=\"date\", columns=\"element\", values=\"amount\")\n", + "pivot_df.fillna(\"\")" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "039ea8ce", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "element=Carer
date=%{x}
amount=%{y}", + "legendgroup": "Carer", + "line": { + "color": "#636efa", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "Carer", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2019-01-01", + "2020-01-01", + "2021-01-01", + "2022-01-01", + "2023-01-01", + "2024-01-01" + ], + "xaxis": "x", + "y": [ + null, + 36, + 37.5, + 37.7, + 38.85, + 38.85 + ], + "yaxis": "y" + }, + { + "hovertemplate": "element=Child
date=%{x}
amount=%{y}", + "legendgroup": "Child", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "Child", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2019-01-01", + "2020-01-01", + "2021-01-01", + "2022-01-01", + "2023-01-01", + "2024-01-01" + ], + "xaxis": "x", + "y": [ + null, + 53.34, + 54.32, + 54.6, + 56.35, + 56.35 + ], + "yaxis": "y" + }, + { + "hovertemplate": "element=Disabled child
date=%{x}
amount=%{y}", + "legendgroup": "Disabled child", + "line": { + "color": "#00cc96", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "Disabled child", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2019-01-01", + "2020-01-01", + "2021-01-01", + "2022-01-01", + "2023-01-01", + "2024-01-01" + ], + "xaxis": "x", + "y": [ + 29.02, + 29.02, + 29.52, + 29.66, + 30.58, + 30.58 + ], + "yaxis": "y" + }, + { + "hovertemplate": "element=Severe disabled child
date=%{x}
amount=%{y}", + "legendgroup": "Severe disabled child", + "line": { + "color": "#ab63fa", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "Severe disabled child", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2019-01-01", + "2020-01-01", + "2021-01-01", + "2022-01-01", + "2023-01-01", + "2024-01-01" + ], + "xaxis": "x", + "y": [ + null, + 88.34, + 92.12, + 92.54, + 95.48, + 95.48 + ], + "yaxis": "y" + }, + { + "hovertemplate": "element=Severe disabled adult
date=%{x}
amount=%{y}", + "legendgroup": "Severe disabled adult", + "line": { + "color": "#FFA15A", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "Severe disabled adult", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2019-01-01", + "2020-01-01", + "2021-01-01", + "2022-01-01", + "2023-01-01", + "2024-01-01" + ], + "xaxis": "x", + "y": [ + 64.3, + 65.85, + 66.95, + 67.3, + 69.4, + 69.4 + ], + "yaxis": "y" + } + ], + "layout": { + "font": { + "color": "black", + "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": "Element" + }, + "tracegroupgap": 0 + }, + "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": "Guarantee Credit elements over time" + }, + "width": 800, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Year" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "range": [ + 0, + 100 + ], + "tickformat": ",.0f", + "tickprefix": "£", + "title": { + "text": "Amount(£m)" + } + } + } + }, + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import plotly.express as px\n", + "from policyengine_core.charts import format_fig\n", + "\n", + "fig = px.line(\n", + " df,\n", + " title=\"Guarantee Credit elements over time\",\n", + " x=\"date\",\n", + " y=\"amount\",\n", + " color=\"element\",\n", + ").update_layout(\n", + " yaxis_range=[0, 100],\n", + " yaxis_tickformat=\",.0f\",\n", + " yaxis_tickprefix=\"£\",\n", + " yaxis_title=\"Amount(£m)\",\n", + " xaxis_title=\"Year\",\n", + " legend_title=\"Element\",\n", + ")\n", + "\n", + "fig = format_fig(fig)\n", + "fig" + ] + }, + { + "cell_type": "markdown", + "id": "99a7da9d", + "metadata": {}, + "source": [ + "Some key components of Savings Credit include:\n", + "\n", + "* Pension credit savings credit income threshold (couple): \n", + " This component represents the income threshold for couples applying for Savings Credit within the Pension Credit program.\n", + " If the total income of a couple (or a person in a couple) falls below this income threshold, they become eligible for Savings Credit. If their income exceeds this threshold, they may not be eligible, or their benefit amount may be reduced.\n", + "\n", + "* Pension credit savings credit income threshold (single):\n", + " Similar to the couple threshold, this component represents the income threshold for single individuals applying for Savings Credit within the Pension Credit program.\n", + " If the total income of a single individual falls below this income threshold, they become eligible for Savings Credit. If their income exceeds this threshold, they may not be eligible, or their benefit amount may be reduced.\n", + "\n", + "* Savings Threshold:\n", + " This threshold represents the maximum amount of savings or assets an individual or couple can have while still being eligible for Savings Credit. If their savings or assets exceed this threshold, it may affect their eligibility or benefit amount.\n", + "\n", + "These components collectively help calculate the entitlement to Savings Credit under the UK's Pension Credit program. \n", + "\n", + "\n", + "The table below shows some of the rates covered by PolicyEngine-UK." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "422226f8", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
elementIncome threshold (couple)Income threshold (single)
date
2015-01-01
2016-01-01201.8126.5
2017-01-01212.97133.82
2018-01-01218.42137.35
2019-01-01223.82140.67
2020-01-01229.67144.38
2021-01-01239.17150.47
2022-01-01244.12153.7
\n", + "
" + ], + "text/plain": [ + "element Income threshold (couple) Income threshold (single)\n", + "date \n", + "2015-01-01 \n", + "2016-01-01 201.8 126.5\n", + "2017-01-01 212.97 133.82\n", + "2018-01-01 218.42 137.35\n", + "2019-01-01 223.82 140.67\n", + "2020-01-01 229.67 144.38\n", + "2021-01-01 239.17 150.47\n", + "2022-01-01 244.12 153.7" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from policyengine_uk.system import system\n", + "\n", + "parameters = system.parameters\n", + "\n", + "threshold_single = (\n", + " parameters.gov.dwp.pension_credit.savings_credit.threshold.SINGLE\n", + ")\n", + "threshold_couple = (\n", + " parameters.gov.dwp.pension_credit.savings_credit.threshold.COUPLE\n", + ")\n", + "\n", + "elements = [threshold_single, threshold_couple] # [...]\n", + "\n", + "dates = [\n", + " \"2015-01-01\",\n", + " \"2016-01-01\",\n", + " \"2017-01-01\",\n", + " \"2018-01-01\",\n", + " \"2019-01-01\",\n", + " \"2020-01-01\",\n", + " \"2021-01-01\",\n", + " \"2022-01-01\",\n", + "]\n", + "names = [\"Income threshold (single)\", \"Income threshold (couple)\"]\n", + "\n", + "import pandas as pd\n", + "\n", + "df = pd.DataFrame()\n", + "\n", + "for date in dates:\n", + " for element, name in zip(elements, names):\n", + " # Append to a dataframe: row = date, column = element, value = amount\n", + " new_row = {\"date\": date, \"element\": name, \"amount\": element(date)}\n", + " # Append row to the dataframe\n", + " df = pd.concat([df, pd.DataFrame([new_row])])\n", + "\n", + "\n", + "# merge element cells\n", + "pivot_df = df.pivot(index=\"date\", columns=\"element\", values=\"amount\")\n", + "pivot_df.fillna(\"\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "7cd622a7", + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "element=Income threshold (single)
date=%{x}
amount=%{y}", + "legendgroup": "Income threshold (single)", + "line": { + "color": "#636efa", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "Income threshold (single)", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2015-01-01", + "2016-01-01", + "2017-01-01", + "2018-01-01", + "2019-01-01", + "2020-01-01", + "2021-01-01", + "2022-01-01" + ], + "xaxis": "x", + "y": [ + null, + 126.5, + 133.82, + 137.35, + 140.67, + 144.38, + 150.47, + 153.7 + ], + "yaxis": "y" + }, + { + "hovertemplate": "element=Income threshold (couple)
date=%{x}
amount=%{y}", + "legendgroup": "Income threshold (couple)", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "Income threshold (couple)", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2015-01-01", + "2016-01-01", + "2017-01-01", + "2018-01-01", + "2019-01-01", + "2020-01-01", + "2021-01-01", + "2022-01-01" + ], + "xaxis": "x", + "y": [ + null, + 201.8, + 212.97, + 218.42, + 223.82, + 229.67, + 239.17, + 244.12 + ], + "yaxis": "y" + } + ], + "layout": { + "font": { + "color": "black", + "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": "Element" + }, + "tracegroupgap": 0 + }, + "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": "Savings Credit elements over time" + }, + "width": 800, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Year" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "range": [ + 0, + 300 + ], + "tickformat": ",.0f", + "tickprefix": "£", + "title": { + "text": "Amount(£m)" + } + } + } + }, + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import plotly.express as px\n", + "from policyengine_core.charts import format_fig\n", + "\n", + "fig = px.line(\n", + " df,\n", + " title=\"Savings Credit elements over time\",\n", + " x=\"date\",\n", + " y=\"amount\",\n", + " color=\"element\",\n", + ").update_layout(\n", + " yaxis_range=[0, 300],\n", + " yaxis_tickformat=\",.0f\",\n", + " yaxis_tickprefix=\"£\",\n", + " yaxis_title=\"Amount(£m)\",\n", + " xaxis_title=\"Year\",\n", + " legend_title=\"Element\",\n", + ")\n", + "\n", + "fig = format_fig(fig)\n", + "fig" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f03a5b1d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/book/programs/gov/dwp/universal-credit.ipynb b/docs/book/programs/gov/dwp/universal-credit.ipynb index 5b074e181..843b7d45b 100644 --- a/docs/book/programs/gov/dwp/universal-credit.ipynb +++ b/docs/book/programs/gov/dwp/universal-credit.ipynb @@ -191,12 +191,32 @@ "carer_amount = parameters.gov.dwp.universal_credit.elements.carer.amount\n", "child_amount = parameters.gov.dwp.universal_credit.elements.child.amount\n", "disabled_amount = parameters.gov.dwp.universal_credit.elements.disabled.amount\n", - "disabled_child_amount = parameters.gov.dwp.universal_credit.elements.child.disabled.amount\n", - "higher_amount = parameters.gov.dwp.universal_credit.elements.child.first.higher_amount\n", + "disabled_child_amount = (\n", + " parameters.gov.dwp.universal_credit.elements.child.disabled.amount\n", + ")\n", + "higher_amount = (\n", + " parameters.gov.dwp.universal_credit.elements.child.first.higher_amount\n", + ")\n", "\n", - "elements = [carer_amount, child_amount, disabled_amount, disabled_child_amount, higher_amount] # [...]\n", + "elements = [\n", + " carer_amount,\n", + " child_amount,\n", + " disabled_amount,\n", + " disabled_child_amount,\n", + " higher_amount,\n", + "] # [...]\n", "\n", - "dates = [\"2016-01-01\", \"2017-01-01\", \"2018-01-01\", \"2019-01-01\", \"2020-01-01\", \"2021-01-01\", \"2022-01-01\", \"2023-01-01\", \"2024-01-01\"]\n", + "dates = [\n", + " \"2016-01-01\",\n", + " \"2017-01-01\",\n", + " \"2018-01-01\",\n", + " \"2019-01-01\",\n", + " \"2020-01-01\",\n", + " \"2021-01-01\",\n", + " \"2022-01-01\",\n", + " \"2023-01-01\",\n", + " \"2024-01-01\",\n", + "]\n", "names = [\"Carer\", \"Child\", \"Disabled\", \"Disabled child\", \"First child\"]\n", "\n", "import pandas as pd\n", @@ -206,18 +226,14 @@ "for date in dates:\n", " for element, name in zip(elements, names):\n", " # Append to a dataframe: row = date, column = element, value = amount\n", - " new_row = {\n", - " \"date\": date,\n", - " \"element\": name,\n", - " \"amount\": element(date)\n", - " }\n", - " # Append row to the dataframe\n", + " new_row = {\"date\": date, \"element\": name, \"amount\": element(date)}\n", + " # Append row to the dataframe\n", " df = pd.concat([df, pd.DataFrame([new_row])])\n", "\n", "\n", "# merge element cells\n", "pivot_df = df.pivot(index=\"date\", columns=\"element\", values=\"amount\")\n", - "pivot_df.fillna(\"\")\n" + "pivot_df.fillna(\"\")" ] }, { @@ -1335,9 +1351,9 @@ " yaxis_range=[0, 500],\n", " yaxis_tickformat=\",.0f\",\n", " yaxis_tickprefix=\"£\",\n", - " yaxis_title = \"Amount(£m)\",\n", - " xaxis_title = \"Year\",\n", - " legend_title = \"Element\"\n", + " yaxis_title=\"Amount(£m)\",\n", + " xaxis_title=\"Year\",\n", + " legend_title=\"Element\",\n", ")\n", "\n", "fig = format_fig(fig)\n", diff --git a/docs/book/programs/gov/hmrc/fuel-duty.ipynb b/docs/book/programs/gov/hmrc/fuel-duty.ipynb index 3c17be186..0c102b20c 100644 --- a/docs/book/programs/gov/hmrc/fuel-duty.ipynb +++ b/docs/book/programs/gov/hmrc/fuel-duty.ipynb @@ -126,12 +126,14 @@ "df = pd.DataFrame()\n", "\n", "df[\"Date of change\"] = [\n", - " parameter.instant_str for parameter in hmrc.fuel_duty.petrol_and_diesel.values_list\n", + " parameter.instant_str\n", + " for parameter in hmrc.fuel_duty.petrol_and_diesel.values_list\n", "]\n", "df[\"Fuel duty rate (£/litre)\"] = [\n", - " parameter.value for parameter in hmrc.fuel_duty.petrol_and_diesel.values_list\n", + " parameter.value\n", + " for parameter in hmrc.fuel_duty.petrol_and_diesel.values_list\n", "]\n", - "df.sort_values(\"Date of change\",inplace=True)\n", + "df.sort_values(\"Date of change\", inplace=True)\n", "df.set_index(\"Date of change\")" ] }, @@ -1054,12 +1056,13 @@ ], "source": [ "import plotly.express as px\n", + "\n", "px.line(\n", " df,\n", " x=\"Date of change\",\n", " y=\"Fuel duty rate (£/litre)\",\n", " title=\"Fuel duty rate on petrol and giesel\",\n", - " color_discrete_sequence=[\"#2C6496\"]\n", + " color_discrete_sequence=[\"#2C6496\"],\n", ").update_layout(\n", " yaxis_title=\"Fuel duty rate per litre\",\n", " yaxis_tickprefix=\"£\",\n", @@ -1068,10 +1071,9 @@ " xaxis_tickformat=\"%Y\",\n", " height=600,\n", " width=800,\n", - " template=\"plotly_white\"\n", + " template=\"plotly_white\",\n", ").update_xaxes(\n", - " tickangle=45,\n", - " tickfont={\"size\":10}\n", + " tickangle=45, tickfont={\"size\": 10}\n", ").update_traces(\n", " line_shape=\"hv\"\n", ")" diff --git a/docs/book/programs/gov/hmrc/national-insurance.ipynb b/docs/book/programs/gov/hmrc/national-insurance.ipynb index e296ee3ab..8bdb55af3 100644 --- a/docs/book/programs/gov/hmrc/national-insurance.ipynb +++ b/docs/book/programs/gov/hmrc/national-insurance.ipynb @@ -1,2741 +1,2742 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "_gdKAFopTwuB" - }, - "source": [ - "# National Insurance" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "b3G5DBwhos_2" - }, - "source": [ - "National Insurance is a key component of the UK tax system. It primarily funds certain types of welfare and state benefits, including the State Pension. Here's an overview of National Insurance:\n", - "\n", - "NI has four main classes:\n", - "\n", - "- **Class 1**: Paid by employees and their employers. This is based on the employee's earnings and is deducted directly from wages.\n", - "- **Class 2**: Paid by self-employed people with profits above a certain threshold.\n", - "- **Class 3**: Voluntary contributions, often made by people who want to fill gaps in their National Insurance record.\n", - "- **Class 4**: Paid by self-employed people with profits above a certain threshold, in addition to Class 2 NICs." - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "_gdKAFopTwuB" + }, + "source": [ + "# National Insurance" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b3G5DBwhos_2" + }, + "source": [ + "National Insurance is a key component of the UK tax system. It primarily funds certain types of welfare and state benefits, including the State Pension. Here's an overview of National Insurance:\n", + "\n", + "NI has four main classes:\n", + "\n", + "- **Class 1**: Paid by employees and their employers. This is based on the employee's earnings and is deducted directly from wages.\n", + "- **Class 2**: Paid by self-employed people with profits above a certain threshold.\n", + "- **Class 3**: Voluntary contributions, often made by people who want to fill gaps in their National Insurance record.\n", + "- **Class 4**: Paid by self-employed people with profits above a certain threshold, in addition to Class 2 NICs." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ie5U-X3ruXj3" + }, + "source": [ + "## Modelling\n", + "\n", + "PolicyEngine models each class separately, according to the table below." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "cellView": "form", + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "SfKRQHzBm1rQ", + "outputId": "ca2e1cc7-616a-433c-c1e3-6a0e95f48fbc", + "tags": [ + "hide-input" + ] + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "ie5U-X3ruXj3" - }, - "source": [ - "## Modelling\n", - "\n", - "PolicyEngine models each class separately, according to the table below." + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ClassMethodology & BasisThresholds & LimitsRate ApplicationReference
0Class 1Based on employment income. \\n- Monthly and an...Primary Threshold, Upper Earnings LimitMain and Additional ratesSocial Security Contributions and Benefits Act...
1Class 2Based on self-employment income. \\n- Weekly fl...Small Profits ThresholdFlat rateSocial Security and Benefits Act 1992 s. 11
2Class 4Derived from self-employment income minus Clas...Lower Profits Limit, Upper Profits LimitMain and Additional ratesSocial Security and Benefits Act 1992 s. 15
\n", + "
" + ], + "text/plain": [ + " Class Methodology & Basis \\\n", + "0 Class 1 Based on employment income. \\n- Monthly and an... \n", + "1 Class 2 Based on self-employment income. \\n- Weekly fl... \n", + "2 Class 4 Derived from self-employment income minus Clas... \n", + "\n", + " Thresholds & Limits Rate Application \\\n", + "0 Primary Threshold, Upper Earnings Limit Main and Additional rates \n", + "1 Small Profits Threshold Flat rate \n", + "2 Lower Profits Limit, Upper Profits Limit Main and Additional rates \n", + "\n", + " Reference \n", + "0 Social Security Contributions and Benefits Act... \n", + "1 Social Security and Benefits Act 1992 s. 11 \n", + "2 Social Security and Benefits Act 1992 s. 15 " ] - }, + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# @title\n", + "import pandas as pd\n", + "from tabulate import tabulate\n", + "\n", + "\n", + "data = {\n", + " \"Class\": [\"Class 1\", \"Class 2\", \"Class 4\"],\n", + " \"Methodology & Basis\": [\n", + " \"Based on employment income. \\n- Monthly and annual calculations.\",\n", + " \"Based on self-employment income. \\n- Weekly flat rate.\",\n", + " \"Derived from self-employment income minus Class 1 employee NI.\",\n", + " ],\n", + " \"Thresholds & Limits\": [\n", + " \"Primary Threshold, Upper Earnings Limit\",\n", + " \"Small Profits Threshold\",\n", + " \"Lower Profits Limit, Upper Profits Limit\",\n", + " ],\n", + " \"Rate Application\": [\n", + " \"Main and Additional rates\",\n", + " \"Flat rate\",\n", + " \"Main and Additional rates\",\n", + " ],\n", + " \"Reference\": [\n", + " \"Social Security Contributions and Benefits Act 1992 s. 8\",\n", + " \"Social Security and Benefits Act 1992 s. 11\",\n", + " \"Social Security and Benefits Act 1992 s. 15\",\n", + " ],\n", + "}\n", + "\n", + "df = pd.DataFrame(data)\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bxQD7vfe1t2n", + "tags": [ + "hide-input" + ] + }, + "source": [ + "## Appendix\n", + "\n", + "The chart below shows all threshold parameters for each class of National Insurance." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "cellView": "form", - "colab": { - "base_uri": "https://localhost:8080/" + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Label=NI Lower Earnings Limit
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Lower Earnings Limit", + "line": { + "color": "#636efa", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Lower Earnings Limit", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 120, + 120, + 123, + 123, + 123, + 123, + 123, + 123, + 123, + 123, + 123, + 123, + 123, + 123 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Label=NI Primary Threshold
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Primary Threshold", + "line": { + "color": "#EF553B", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Primary Threshold", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 183, + 184, + 190, + 241.73, + 241.73, + 241.73, + 241.73, + 241.73, + 241.73, + 241.73, + 241.73, + 241.73, + 241.73, + 241.73 + ], + "yaxis": "y" }, - "id": "SfKRQHzBm1rQ", - "outputId": "ca2e1cc7-616a-433c-c1e3-6a0e95f48fbc", - "tags": [ - "hide-input" - ] - }, - "outputs": [ { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ClassMethodology & BasisThresholds & LimitsRate ApplicationReference
0Class 1Based on employment income. \\n- Monthly and an...Primary Threshold, Upper Earnings LimitMain and Additional ratesSocial Security Contributions and Benefits Act...
1Class 2Based on self-employment income. \\n- Weekly fl...Small Profits ThresholdFlat rateSocial Security and Benefits Act 1992 s. 11
2Class 4Derived from self-employment income minus Clas...Lower Profits Limit, Upper Profits LimitMain and Additional ratesSocial Security and Benefits Act 1992 s. 15
\n", - "
" - ], - "text/plain": [ - " Class Methodology & Basis \\\n", - "0 Class 1 Based on employment income. \\n- Monthly and an... \n", - "1 Class 2 Based on self-employment income. \\n- Weekly fl... \n", - "2 Class 4 Derived from self-employment income minus Clas... \n", - "\n", - " Thresholds & Limits Rate Application \\\n", - "0 Primary Threshold, Upper Earnings Limit Main and Additional rates \n", - "1 Small Profits Threshold Flat rate \n", - "2 Lower Profits Limit, Upper Profits Limit Main and Additional rates \n", - "\n", - " Reference \n", - "0 Social Security Contributions and Benefits Act... \n", - "1 Social Security and Benefits Act 1992 s. 11 \n", - "2 Social Security and Benefits Act 1992 s. 15 " + "hovertemplate": "Label=NI Upper Earnings Limit
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Upper Earnings Limit", + "line": { + "color": "#00cc96", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Upper Earnings Limit", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 962, + 966.73, + 966.73, + 966.73, + 966.73, + 966.73, + 966.73, + 966.73, + 966.73, + 966.73, + 966.73, + 966.73, + 966.73, + 966.73 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Label=NI Secondary Threshold
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Secondary Threshold", + "line": { + "color": "#ab63fa", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Secondary Threshold", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 169, + 170, + 175, + 175, + 175, + 175, + 175, + 175, + 175, + 175, + 175, + 175, + 175, + 175 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Label=NI Class 2 Small Profits Threshold
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Class 2 Small Profits Threshold", + "line": { + "color": "#FFA15A", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Class 2 Small Profits Threshold", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 6475, + 6515, + 6725, + 6725, + 6725, + 6725, + 6725, + 6725, + 6725, + 6725, + 6725, + 6725, + 6725, + 6725 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Label=NI Lower Profits Limit
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Lower Profits Limit", + "line": { + "color": "#19d3f3", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Lower Profits Limit", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 9500, + 9568, + 11908, + 11908, + 11908, + 11908, + 12570, + 12570, + 12570, + 12570, + 12570, + 12570, + 12570, + 12570 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Label=NI Upper Profits Limit
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Upper Profits Limit", + "line": { + "color": "#FF6692", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Upper Profits Limit", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 50000, + 50270, + 50270, + 50270, + 50270, + 50270, + 50270, + 50270, + 50270, + 50270, + 50270, + 50270, + 50270, + 50270 + ], + "yaxis": "y" + } + ], + "layout": { + "font": { + "color": "black", + "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": { + "orientation": "h", + "title": { + "text": "" + }, + "tracegroupgap": 0, + "x": 1, + "xanchor": "right", + "y": -0.3, + "yanchor": "bottom" + }, + "margin": { + "t": 60 + }, + "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" ] + ] }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# @title\n", - "import pandas as pd\n", - "from tabulate import tabulate\n", - "\n", - "\n", - "data = {\n", - " \"Class\": [\"Class 1\", \"Class 2\", \"Class 4\"],\n", - " \"Methodology & Basis\": [\n", - " \"Based on employment income. \\n- Monthly and annual calculations.\",\n", - " \"Based on self-employment income. \\n- Weekly flat rate.\",\n", - " \"Derived from self-employment income minus Class 1 employee NI.\"\n", - " ],\n", - " \"Thresholds & Limits\": [\n", - " \"Primary Threshold, Upper Earnings Limit\",\n", - " \"Small Profits Threshold\",\n", - " \"Lower Profits Limit, Upper Profits Limit\"\n", - " ],\n", - " \"Rate Application\": [\n", - " \"Main and Additional rates\",\n", - " \"Flat rate\",\n", - " \"Main and Additional rates\"\n", - " ],\n", - " \"Reference\": [\n", - " \"Social Security Contributions and Benefits Act 1992 s. 8\",\n", - " \"Social Security and Benefits Act 1992 s. 11\",\n", - " \"Social Security and Benefits Act 1992 s. 15\"\n", - " ]\n", - "}\n", - "\n", - "df = pd.DataFrame(data)\n", - "df\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "bxQD7vfe1t2n", - "tags": [ - "hide-input" - ] - }, - "source": [ - "## Appendix\n", - "\n", - "The chart below shows all threshold parameters for each class of National Insurance." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "Label=NI Lower Earnings Limit
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Lower Earnings Limit", - "line": { - "color": "#636efa", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Lower Earnings Limit", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 120, - 120, - 123, - 123, - 123, - 123, - 123, - 123, - 123, - 123, - 123, - 123, - 123, - 123 - ], - "yaxis": "y" - }, - { - "hovertemplate": "Label=NI Primary Threshold
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Primary Threshold", - "line": { - "color": "#EF553B", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Primary Threshold", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 183, - 184, - 190, - 241.73, - 241.73, - 241.73, - 241.73, - 241.73, - 241.73, - 241.73, - 241.73, - 241.73, - 241.73, - 241.73 - ], - "yaxis": "y" - }, - { - "hovertemplate": "Label=NI Upper Earnings Limit
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Upper Earnings Limit", - "line": { - "color": "#00cc96", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Upper Earnings Limit", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 962, - 966.73, - 966.73, - 966.73, - 966.73, - 966.73, - 966.73, - 966.73, - 966.73, - 966.73, - 966.73, - 966.73, - 966.73, - 966.73 - ], - "yaxis": "y" - }, - { - "hovertemplate": "Label=NI Secondary Threshold
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Secondary Threshold", - "line": { - "color": "#ab63fa", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Secondary Threshold", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 169, - 170, - 175, - 175, - 175, - 175, - 175, - 175, - 175, - 175, - 175, - 175, - 175, - 175 - ], - "yaxis": "y" - }, - { - "hovertemplate": "Label=NI Class 2 Small Profits Threshold
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Class 2 Small Profits Threshold", - "line": { - "color": "#FFA15A", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Class 2 Small Profits Threshold", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 6475, - 6515, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725, - 6725 - ], - "yaxis": "y" - }, - { - "hovertemplate": "Label=NI Lower Profits Limit
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Lower Profits Limit", - "line": { - "color": "#19d3f3", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Lower Profits Limit", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 9500, - 9568, - 11908, - 11908, - 11908, - 11908, - 12570, - 12570, - 12570, - 12570, - 12570, - 12570, - 12570, - 12570 - ], - "yaxis": "y" - }, - { - "hovertemplate": "Label=NI Upper Profits Limit
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Upper Profits Limit", - "line": { - "color": "#FF6692", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Upper Profits Limit", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 50000, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270, - 50270 - ], - "yaxis": "y" - } - ], - "layout": { - "font": { - "color": "black", - "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": { - "orientation": "h", - "title": { - "text": "" - }, - "tracegroupgap": 0, - "x": 1, - "xanchor": "right", - "y": -0.3, - "yanchor": "bottom" - }, - "margin": { - "t": 60 - }, - "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": "National Insurance thresholds over time" - }, - "width": 800, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Instant" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Value" - } - } - } - } + "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": "" + } }, - "metadata": {}, - "output_type": "display_data" + "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": "National Insurance thresholds over time" + }, + "width": 800, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Instant" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Value" + } } - ], - "source": [ - "from policyengine_uk.system import system\n", - "import plotly.express as px\n", - "from policyengine_core.charts import format_fig\n", - "from policyengine_core.parameters import Parameter\n", - "\n", - "ni = system.parameters.gov.hmrc.national_insurance\n", - "\n", - "threshold_parameters = [\n", - " ni.class_1.thresholds.lower_earnings_limit,\n", - " ni.class_1.thresholds.primary_threshold,\n", - " ni.class_1.thresholds.upper_earnings_limit,\n", - " ni.class_1.thresholds.secondary_threshold,\n", - " ni.class_2.small_profits_threshold,\n", - " ni.class_4.thresholds.lower_profits_limit,\n", - " ni.class_4.thresholds.upper_profits_limit\n", - "]\n", - "rate_parameters = [\n", - " param for param in ni.get_descendants() if param not in threshold_parameters\n", - " and isinstance(param, Parameter)\n", - "]\n", - "\n", - "instants = [\n", - " f\"{2020 + i}-04-06\" for i in range(0, 14)\n", - "]\n", - "\n", - "instant_values = []\n", - "values = []\n", - "is_thresholds = []\n", - "labels = []\n", - "\n", - "for param in threshold_parameters:\n", - " for instant in instants:\n", - " instant_values.append(instant)\n", - " values.append(param(instant))\n", - " is_thresholds.append(True)\n", - " labels.append(param.metadata.get(\"label\"))\n", - "\n", - "for param in rate_parameters:\n", - " for instant in instants:\n", - " instant_values.append(instant)\n", - " values.append(param(instant))\n", - " is_thresholds.append(False)\n", - " labels.append(param.metadata.get(\"label\"))\n", - "\n", - "df = pd.DataFrame({\n", - " \"Instant\": instant_values,\n", - " \"Value\": values,\n", - " \"Threshold\": is_thresholds,\n", - " \"Label\": labels\n", - "})\n", - "\n", - "fig = px.line(\n", - " df[df[\"Threshold\"] == True],\n", - " x=\"Instant\",\n", - " y=\"Value\",\n", - " color=\"Label\",\n", - ")\n", - "\n", - "fig.update_layout(\n", - " title=\"National Insurance thresholds over time\",\n", - " # Put legend at bottom\n", - " legend=dict(\n", - " orientation=\"h\",\n", - " yanchor=\"bottom\",\n", - " y=-0.3,\n", - " xanchor=\"right\",\n", - " x=1,\n", - " title=\"\",\n", - " ),\n", - ")\n", - "\n", - "fig.update_traces(\n", - " line_shape=\"hv\",\n", - ")\n", - "\n", - "fig = format_fig(fig)\n", - "fig" - ] - }, + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from policyengine_uk.system import system\n", + "import plotly.express as px\n", + "from policyengine_core.charts import format_fig\n", + "from policyengine_core.parameters import Parameter\n", + "\n", + "ni = system.parameters.gov.hmrc.national_insurance\n", + "\n", + "threshold_parameters = [\n", + " ni.class_1.thresholds.lower_earnings_limit,\n", + " ni.class_1.thresholds.primary_threshold,\n", + " ni.class_1.thresholds.upper_earnings_limit,\n", + " ni.class_1.thresholds.secondary_threshold,\n", + " ni.class_2.small_profits_threshold,\n", + " ni.class_4.thresholds.lower_profits_limit,\n", + " ni.class_4.thresholds.upper_profits_limit,\n", + "]\n", + "rate_parameters = [\n", + " param\n", + " for param in ni.get_descendants()\n", + " if param not in threshold_parameters and isinstance(param, Parameter)\n", + "]\n", + "\n", + "instants = [f\"{2020 + i}-04-06\" for i in range(0, 14)]\n", + "\n", + "instant_values = []\n", + "values = []\n", + "is_thresholds = []\n", + "labels = []\n", + "\n", + "for param in threshold_parameters:\n", + " for instant in instants:\n", + " instant_values.append(instant)\n", + " values.append(param(instant))\n", + " is_thresholds.append(True)\n", + " labels.append(param.metadata.get(\"label\"))\n", + "\n", + "for param in rate_parameters:\n", + " for instant in instants:\n", + " instant_values.append(instant)\n", + " values.append(param(instant))\n", + " is_thresholds.append(False)\n", + " labels.append(param.metadata.get(\"label\"))\n", + "\n", + "df = pd.DataFrame(\n", + " {\n", + " \"Instant\": instant_values,\n", + " \"Value\": values,\n", + " \"Threshold\": is_thresholds,\n", + " \"Label\": labels,\n", + " }\n", + ")\n", + "\n", + "fig = px.line(\n", + " df[df[\"Threshold\"] == True],\n", + " x=\"Instant\",\n", + " y=\"Value\",\n", + " color=\"Label\",\n", + ")\n", + "\n", + "fig.update_layout(\n", + " title=\"National Insurance thresholds over time\",\n", + " # Put legend at bottom\n", + " legend=dict(\n", + " orientation=\"h\",\n", + " yanchor=\"bottom\",\n", + " y=-0.3,\n", + " xanchor=\"right\",\n", + " x=1,\n", + " title=\"\",\n", + " ),\n", + ")\n", + "\n", + "fig.update_traces(\n", + " line_shape=\"hv\",\n", + ")\n", + "\n", + "fig = format_fig(fig)\n", + "fig" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The chart below shows all rate parameters for each class of National Insurance." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The chart below shows all rate parameters for each class of National Insurance." - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "/var/folders/8f/pgfhysmd5ls3jnxb_5j7yy340000gn/T/ipykernel_41381/4247299465.py:2: UserWarning:\n", + "\n", + "Boolean Series key will be reindexed to match DataFrame index.\n", + "\n" + ] }, { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/8f/pgfhysmd5ls3jnxb_5j7yy340000gn/T/ipykernel_41381/4247299465.py:2: UserWarning:\n", - "\n", - "Boolean Series key will be reindexed to match DataFrame index.\n", - "\n" - ] + "hovertemplate": "Label=NI Class 4 additional rate
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Class 4 additional rate", + "line": { + "color": "#636efa", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Class 4 additional rate", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 0.02, + 0.02, + 0.035, + 0.035, + 0.035, + 0.035, + 0.035, + 0.035, + 0.035, + 0.035, + 0.035, + 0.035, + 0.035, + 0.035 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Label=NI Class 4 main rate
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Class 4 main rate", + "line": { + "color": "#EF553B", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Class 4 main rate", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 0.09, + 0.09, + 0.1025, + 0.09, + 0.09, + 0.09, + 0.09, + 0.09, + 0.09, + 0.09, + 0.09, + 0.09, + 0.09, + 0.09 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Label=NI Class 1 additional rate
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Class 1 additional rate", + "line": { + "color": "#00cc96", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Class 1 additional rate", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 0.02, + 0.02, + 0.0325, + 0.0325, + 0.0325, + 0.0325, + 0.0325, + 0.0325, + 0.0325, + 0.0325, + 0.0325, + 0.0325, + 0.0325, + 0.0325 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Label=NI Class 1 main rate
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Class 1 main rate", + "line": { + "color": "#ab63fa", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Class 1 main rate", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 0.12, + 0.12, + 0.1325, + 0.12, + 0.12, + 0.12, + 0.12, + 0.12, + 0.12, + 0.12, + 0.12, + 0.12, + 0.12, + 0.12 + ], + "yaxis": "y" }, { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "Label=NI Class 4 additional rate
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Class 4 additional rate", - "line": { - "color": "#636efa", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Class 4 additional rate", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 0.02, - 0.02, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035, - 0.035 - ], - "yaxis": "y" - }, - { - "hovertemplate": "Label=NI Class 4 main rate
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Class 4 main rate", - "line": { - "color": "#EF553B", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Class 4 main rate", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 0.09, - 0.09, - 0.1025, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09, - 0.09 - ], - "yaxis": "y" - }, - { - "hovertemplate": "Label=NI Class 1 additional rate
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Class 1 additional rate", - "line": { - "color": "#00cc96", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Class 1 additional rate", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 0.02, - 0.02, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325, - 0.0325 - ], - "yaxis": "y" - }, - { - "hovertemplate": "Label=NI Class 1 main rate
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Class 1 main rate", - "line": { - "color": "#ab63fa", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Class 1 main rate", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 0.12, - 0.12, - 0.1325, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12, - 0.12 - ], - "yaxis": "y" - }, - { - "hovertemplate": "Label=NI Employer rate
Instant=%{x}
Value=%{y}", - "legendgroup": "NI Employer rate", - "line": { - "color": "#FFA15A", - "dash": "solid", - "shape": "hv" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "NI Employer rate", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - "2020-04-06", - "2021-04-06", - "2022-04-06", - "2023-04-06", - "2024-04-06", - "2025-04-06", - "2026-04-06", - "2027-04-06", - "2028-04-06", - "2029-04-06", - "2030-04-06", - "2031-04-06", - "2032-04-06", - "2033-04-06" - ], - "xaxis": "x", - "y": [ - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138, - 0.138 - ], - "yaxis": "y" - } - ], - "layout": { - "font": { - "color": "black", - "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": { - "orientation": "h", - "title": { - "text": "" - }, - "tracegroupgap": 0, - "x": 1, - "xanchor": "right", - "y": -0.3, - "yanchor": "bottom" - }, - "margin": { - "t": 60 - }, - "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": "National Insurance rates over time" - }, - "width": 800, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Instant" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Value" - } - } - } - } + "hovertemplate": "Label=NI Employer rate
Instant=%{x}
Value=%{y}", + "legendgroup": "NI Employer rate", + "line": { + "color": "#FFA15A", + "dash": "solid", + "shape": "hv" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "NI Employer rate", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + "2020-04-06", + "2021-04-06", + "2022-04-06", + "2023-04-06", + "2024-04-06", + "2025-04-06", + "2026-04-06", + "2027-04-06", + "2028-04-06", + "2029-04-06", + "2030-04-06", + "2031-04-06", + "2032-04-06", + "2033-04-06" + ], + "xaxis": "x", + "y": [ + 0.138, + 0.138, + 0.138, + 0.138, + 0.138, + 0.138, + 0.138, + 0.138, + 0.138, + 0.138, + 0.138, + 0.138, + 0.138, + 0.138 + ], + "yaxis": "y" + } + ], + "layout": { + "font": { + "color": "black", + "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": { + "orientation": "h", + "title": { + "text": "" + }, + "tracegroupgap": 0, + "x": 1, + "xanchor": "right", + "y": -0.3, + "yanchor": "bottom" + }, + "margin": { + "t": 60 + }, + "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 }, - "metadata": {}, - "output_type": "display_data" + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "National Insurance rates over time" + }, + "width": 800, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Instant" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Value" + } } - ], - "source": [ - "fig = px.line(\n", - " df[df[\"Threshold\"] == False][df.Value < 1], # Don't plot the flat rate,\n", - " x=\"Instant\",\n", - " y=\"Value\",\n", - " color=\"Label\",\n", - ")\n", - "\n", - "fig.update_layout(\n", - " title=\"National Insurance rates over time\",\n", - " # Put legend at bottom\n", - " legend=dict(\n", - " orientation=\"h\",\n", - " yanchor=\"bottom\",\n", - " y=-0.3,\n", - " xanchor=\"right\",\n", - " x=1,\n", - " title=\"\",\n", - " ),\n", - ")\n", - "\n", - "fig.update_traces(\n", - " line_shape=\"hv\",\n", - ")\n", - "\n", - "fig = format_fig(fig)\n", - "fig" - ] - } - ], - "metadata": { - "colab": { - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3", - "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" + } + } + }, + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "fig = px.line(\n", + " df[df[\"Threshold\"] == False][df.Value < 1], # Don't plot the flat rate,\n", + " x=\"Instant\",\n", + " y=\"Value\",\n", + " color=\"Label\",\n", + ")\n", + "\n", + "fig.update_layout(\n", + " title=\"National Insurance rates over time\",\n", + " # Put legend at bottom\n", + " legend=dict(\n", + " orientation=\"h\",\n", + " yanchor=\"bottom\",\n", + " y=-0.3,\n", + " xanchor=\"right\",\n", + " x=1,\n", + " title=\"\",\n", + " ),\n", + ")\n", + "\n", + "fig.update_traces(\n", + " line_shape=\"hv\",\n", + ")\n", + "\n", + "fig = format_fig(fig)\n", + "fig" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" }, - "nbformat": 4, - "nbformat_minor": 0 + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 0 } diff --git a/docs/book/programs/gov/hmrc/stamp-duty.ipynb b/docs/book/programs/gov/hmrc/stamp-duty.ipynb index 04a7bca9a..8423418c5 100644 --- a/docs/book/programs/gov/hmrc/stamp-duty.ipynb +++ b/docs/book/programs/gov/hmrc/stamp-duty.ipynb @@ -1196,59 +1196,79 @@ "import plotly.express as px\n", "from policyengine_core.charts import format_fig\n", "\n", - "residential_rent = pd.DataFrame({\n", - " \"Threshold\": [0, 125000, 5200000],\n", - " \"Rate\": [0, 0.01, 0.01],\n", - " \"Label\": [\"Residential rent\"]*3\n", - "})\n", - "residential_purchase_main_first = pd.DataFrame({\n", - " \"Threshold\": [0, 300000, 500000, 925000, 1500000, 5200000], \n", - " \"Rate\": [0, 0.05, 0.05, 0.1, 0.12, 0.12], \n", - " \"Label\": [\"Residential purchase main (first home)\"]*6 \n", - "})\n", - "residential_purchase_main_standard = pd.DataFrame({\n", - " \"Threshold\": [0, 125000, 250000, 925000, 1500000, 5200000],\n", - " \"Rate\": [0, 0.02, 0.05, 0.1, 0.12, 0.12],\n", - " \"Label\": [\"Residential purchase main standard\"]*6\n", - "})\n", - "residential_purchase_additional = pd.DataFrame({\n", - " \"Threshold\": [0, 40000, 125000, 250000, 925000, 1500000, 5200000], \n", - " \"Rate\": [0, 0.03, 0.05, 0.08, 0.13, 0.15, 0.15], \n", - " \"Label\": [\"Residential purchase additional\"]*7\n", - "})\n", - "non_residential_rent = pd.DataFrame({\n", - " \"Threshold\": [0, 150000, 5000000, 5200000],\n", - " \"Rate\": [0, 0.01, 0.02, 0.02],\n", - " \"Label\": [\"Non-residential rent\"]*4\n", - "})\n", - "non_residential_purchase = pd.DataFrame({\n", - " \"Threshold\": [0, 150000, 250000, 5200000],\n", - " \"Rate\": [0, 0.02, 0.05, 0.05],\n", - " \"Label\": [\"Non-residential purchase\"]*4\n", - "})\n", - "df_list = [residential_rent, residential_purchase_main_first, residential_purchase_main_standard, residential_purchase_additional,\n", - " non_residential_rent, non_residential_purchase]\n", + "residential_rent = pd.DataFrame(\n", + " {\n", + " \"Threshold\": [0, 125000, 5200000],\n", + " \"Rate\": [0, 0.01, 0.01],\n", + " \"Label\": [\"Residential rent\"] * 3,\n", + " }\n", + ")\n", + "residential_purchase_main_first = pd.DataFrame(\n", + " {\n", + " \"Threshold\": [0, 300000, 500000, 925000, 1500000, 5200000],\n", + " \"Rate\": [0, 0.05, 0.05, 0.1, 0.12, 0.12],\n", + " \"Label\": [\"Residential purchase main (first home)\"] * 6,\n", + " }\n", + ")\n", + "residential_purchase_main_standard = pd.DataFrame(\n", + " {\n", + " \"Threshold\": [0, 125000, 250000, 925000, 1500000, 5200000],\n", + " \"Rate\": [0, 0.02, 0.05, 0.1, 0.12, 0.12],\n", + " \"Label\": [\"Residential purchase main standard\"] * 6,\n", + " }\n", + ")\n", + "residential_purchase_additional = pd.DataFrame(\n", + " {\n", + " \"Threshold\": [0, 40000, 125000, 250000, 925000, 1500000, 5200000],\n", + " \"Rate\": [0, 0.03, 0.05, 0.08, 0.13, 0.15, 0.15],\n", + " \"Label\": [\"Residential purchase additional\"] * 7,\n", + " }\n", + ")\n", + "non_residential_rent = pd.DataFrame(\n", + " {\n", + " \"Threshold\": [0, 150000, 5000000, 5200000],\n", + " \"Rate\": [0, 0.01, 0.02, 0.02],\n", + " \"Label\": [\"Non-residential rent\"] * 4,\n", + " }\n", + ")\n", + "non_residential_purchase = pd.DataFrame(\n", + " {\n", + " \"Threshold\": [0, 150000, 250000, 5200000],\n", + " \"Rate\": [0, 0.02, 0.05, 0.05],\n", + " \"Label\": [\"Non-residential purchase\"] * 4,\n", + " }\n", + ")\n", + "df_list = [\n", + " residential_rent,\n", + " residential_purchase_main_first,\n", + " residential_purchase_main_standard,\n", + " residential_purchase_additional,\n", + " non_residential_rent,\n", + " non_residential_purchase,\n", + "]\n", "df = pd.concat(df_list)\n", "# plot\n", - "fig = px.line(\n", - " df,\n", - " x=\"Threshold\",\n", - " y=\"Rate\",\n", - " color=\"Label\",\n", - " title = \"Stamp duty land tax rates over property price thresholds\"\n", - ").update_layout(\n", - " yaxis_tickformat=\",.0%\",\n", - " xaxis_tickprefix=\"£\",\n", - " legend=dict(\n", - " orientation=\"h\",\n", - " yanchor=\"bottom\",\n", - " y=-0.3,\n", - " xanchor=\"right\",\n", - " x=0.9,\n", - " title=''\n", + "fig = (\n", + " px.line(\n", + " df,\n", + " x=\"Threshold\",\n", + " y=\"Rate\",\n", + " color=\"Label\",\n", + " title=\"Stamp duty land tax rates over property price thresholds\",\n", " )\n", - ").update_traces(\n", - " line_shape=\"hv\"\n", + " .update_layout(\n", + " yaxis_tickformat=\",.0%\",\n", + " xaxis_tickprefix=\"£\",\n", + " legend=dict(\n", + " orientation=\"h\",\n", + " yanchor=\"bottom\",\n", + " y=-0.3,\n", + " xanchor=\"right\",\n", + " x=0.9,\n", + " title=\"\",\n", + " ),\n", + " )\n", + " .update_traces(line_shape=\"hv\")\n", ")\n", "fig = format_fig(fig)\n", "fig" @@ -6241,7 +6261,7 @@ " households=dict(\n", " household=dict(\n", " main_residential_property_purchased_is_first_home=True,\n", - " members=[\"person\"]\n", + " members=[\"person\"],\n", " )\n", " ),\n", " people=dict(\n", @@ -6249,14 +6269,16 @@ " age=30,\n", " )\n", " ),\n", - " axes=[[\n", - " dict(\n", - " name=\"main_residential_property_purchased\",\n", - " min=0,\n", - " max=5_000_000,\n", - " count=1_000,\n", - " )\n", - " ]]\n", + " axes=[\n", + " [\n", + " dict(\n", + " name=\"main_residential_property_purchased\",\n", + " min=0,\n", + " max=5_000_000,\n", + " count=1_000,\n", + " )\n", + " ]\n", + " ],\n", " )\n", ")\n", "\n", @@ -6265,58 +6287,48 @@ "stamp_duty = sim.calculate(\"stamp_duty_land_tax\")\n", "home_price = sim.calculate(\"main_residential_property_purchased\")\n", "\n", - "marginal_rate = (stamp_duty[1:] - stamp_duty[:-1]) / (home_price[1:] - home_price[:-1])\n", + "marginal_rate = (stamp_duty[1:] - stamp_duty[:-1]) / (\n", + " home_price[1:] - home_price[:-1]\n", + ")\n", "home_price = home_price[:-1]\n", "\n", - "df = pd.DataFrame({\n", - " \"Home price\": home_price,\n", - " \"Marginal SDLT rate\": marginal_rate,\n", - " \"SDLT\": stamp_duty[:-1]\n", - "})\n", + "df = pd.DataFrame(\n", + " {\n", + " \"Home price\": home_price,\n", + " \"Marginal SDLT rate\": marginal_rate,\n", + " \"SDLT\": stamp_duty[:-1],\n", + " }\n", + ")\n", "\n", "import plotly.express as px\n", "from plotly.subplots import make_subplots\n", "\n", "# left shows marginal rate, right shows total SDLT\n", "\n", - "fig = make_subplots(rows=1, cols=2, subplot_titles=(\"Marginal SDLT rate\", \"Total SDLT\"))\n", + "fig = make_subplots(\n", + " rows=1, cols=2, subplot_titles=(\"Marginal SDLT rate\", \"Total SDLT\")\n", + ")\n", "\n", "fig.add_trace(\n", " px.line(\n", - " df,\n", - " x=\"Home price\",\n", - " y=\"Marginal SDLT rate\",\n", - " title = \"Marginal SDLT rate\"\n", - " ).update_traces(\n", - " line_shape=\"hv\"\n", - " ).data[0],\n", - " row=1, col=1\n", - ").update_xaxes(\n", - " row=1, col=1,\n", - " title_text=\"Price\",\n", - " tickprefix=\"£\"\n", - ").update_yaxes(\n", - " row=1, col=1,\n", - " tickformat=\",.0%\"\n", + " df, x=\"Home price\", y=\"Marginal SDLT rate\", title=\"Marginal SDLT rate\"\n", + " )\n", + " .update_traces(line_shape=\"hv\")\n", + " .data[0],\n", + " row=1,\n", + " col=1,\n", + ").update_xaxes(row=1, col=1, title_text=\"Price\", tickprefix=\"£\").update_yaxes(\n", + " row=1, col=1, tickformat=\",.0%\"\n", ")\n", "\n", "fig.add_trace(\n", - " px.line(\n", - " df,\n", - " x=\"Home price\",\n", - " y=\"SDLT\",\n", - " title = \"Total SDLT\"\n", - " ).update_traces(\n", - " line_shape=\"hv\"\n", - " ).data[0],\n", - " row=1, col=2\n", - ").update_xaxes(\n", - " row=1, col=2,\n", - " title_text=\"Price\",\n", - " tickprefix=\"£\"\n", - ").update_yaxes(\n", - " row=1, col=2,\n", - " tickprefix=\"£\"\n", + " px.line(df, x=\"Home price\", y=\"SDLT\", title=\"Total SDLT\")\n", + " .update_traces(line_shape=\"hv\")\n", + " .data[0],\n", + " row=1,\n", + " col=2,\n", + ").update_xaxes(row=1, col=2, title_text=\"Price\", tickprefix=\"£\").update_yaxes(\n", + " row=1, col=2, tickprefix=\"£\"\n", ")\n", "\n", "fig = format_fig(fig)\n", @@ -7294,51 +7306,48 @@ "source": [ "from policyengine_uk.system import system\n", "from policyengine_core.charts import format_fig\n", + "\n", "sdlt = system.parameters.gov.hmrc.stamp_duty.statistics\n", - "stats = {\n", - " \"Year\": [],\n", - " \"Revenue (£m)\": [],\n", - " \"Type\": []\n", - "}\n", + "stats = {\"Year\": [], \"Revenue (£m)\": [], \"Type\": []}\n", "# residential corporate\n", "for parameter in sdlt.residential.corporate.revenue.values_list:\n", " stats[\"Year\"].append(parameter.instant_str[:4])\n", - " stats[\"Revenue (£m)\"].append(parameter.value/1000000)\n", + " stats[\"Revenue (£m)\"].append(parameter.value / 1000000)\n", " stats[\"Type\"].append(\"Residental corporate\")\n", "# residential household\n", "for parameter in sdlt.residential.household.revenue.values_list:\n", " stats[\"Year\"].append(parameter.instant_str[:4])\n", - " stats[\"Revenue (£m)\"].append(parameter.value/1000000)\n", + " stats[\"Revenue (£m)\"].append(parameter.value / 1000000)\n", " stats[\"Type\"].append(\"Residental household\")\n", "# non-residential corporate\n", "for parameter in sdlt.non_residential.corporate.revenue.values_list:\n", " stats[\"Year\"].append(parameter.instant_str[:4])\n", - " stats[\"Revenue (£m)\"].append(parameter.value/1000000)\n", + " stats[\"Revenue (£m)\"].append(parameter.value / 1000000)\n", " stats[\"Type\"].append(\"Non-residental corporate\")\n", "# non-residential household\n", "for parameter in sdlt.non_residential.household.revenue.values_list:\n", " stats[\"Year\"].append(parameter.instant_str[:4])\n", - " stats[\"Revenue (£m)\"].append(parameter.value/1000000)\n", + " stats[\"Revenue (£m)\"].append(parameter.value / 1000000)\n", " stats[\"Type\"].append(\"Non-residental household\")\n", "\n", "df = pd.DataFrame(stats)\n", "df.sort_values(\"Year\", inplace=True)\n", - "fig = px.bar(\n", - " df,\n", - " x=\"Type\",\n", - " y=\"Revenue (£m)\",\n", - " color=\"Year\",\n", - " barmode=\"group\",\n", - " text_auto=True,\n", - " title=\"SDLT statistics for 2019 and 2020\",\n", - " height=500\n", - ").update_traces(\n", - " textposition=\"outside\"\n", - ").update_layout(\n", - " xaxis_title=\"Property type\"\n", + "fig = (\n", + " px.bar(\n", + " df,\n", + " x=\"Type\",\n", + " y=\"Revenue (£m)\",\n", + " color=\"Year\",\n", + " barmode=\"group\",\n", + " text_auto=True,\n", + " title=\"SDLT statistics for 2019 and 2020\",\n", + " height=500,\n", + " )\n", + " .update_traces(textposition=\"outside\")\n", + " .update_layout(xaxis_title=\"Property type\")\n", ")\n", "fig = format_fig(fig)\n", - "fig\n" + "fig" ] } ],