Pennsylvania#

This notebook shows how Pennsylvania’s income tax, including credits, operates holistically.

Examples#

from policyengine_us import IndividualSim
import pandas as pd
import plotly.express as px

LIGHT_GRAY = "#F5F5F5"
GRAY = "#BDBDBD"
BLUE = "#5091cc"
LIGHT_BLUE = "lightblue"
DARK_BLUE = "darkblue"


def make_tax(adults, children):
    sim = IndividualSim(year=2022)
    sim.add_person(name="head", age=25)
    members = ["head"]
    if adults == 2:
        sim.add_person(name="spouse", age=25)
        members += ["spouse"]
    for i in range(children):
        child = "child{}".format(i)
        sim.add_person(name=child, age=6)
        members += [child]
    sim.add_tax_unit(name="tax_unit", members=members, premium_tax_credit=0)
    sim.add_household(name="household", members=members, state_code="PA")
    sim.vary("employment_income", max=100_000, step=1_000)
    employment_income = sim.calc("employment_income")[0]
    state_income_tax = sim.calc("state_income_tax")[0].round()
    mtr = sim.deriv("state_income_tax", "employment_income", wrt_target="head")
    return pd.DataFrame(
        dict(
            employment_income=employment_income,
            state_income_tax=state_income_tax,
            mtr=mtr,
            adults=adults,
            children=str(children),
        )
    )


# Make a table of state taxes for different numbers of adults and children.
l = []
for adults in range(1, 3):
    for children in range(0, 4):
        l.append(make_tax(adults, children))

df = pd.concat(l)

LABELS = dict(
    employment_income="Employment income",
    state_income_tax="Pennsylvania income tax",
    mtr="Marginal tax rate",
    adults="Adults",
    children="Children",
)

COLOR_MAP = {"0": GRAY, "1": LIGHT_BLUE, "2": BLUE, "3": DARK_BLUE}

fig = px.line(
    df,
    "employment_income",
    "state_income_tax",
    color="children",
    animation_frame="adults",
    labels=LABELS,
    title="Pennsylvania income tax",
    color_discrete_map=COLOR_MAP,
)
fig.update_layout(
    xaxis_tickformat="$,",
    yaxis_tickformat="$,",
    plot_bgcolor="white",
    xaxis_gridcolor=LIGHT_GRAY,
    yaxis_gridcolor=LIGHT_GRAY,
)
fig.show()

Total marginal tax rates are typically 3.07%, though the forgiveness raises them as high as 55%.

fig = px.line(
    df,
    "employment_income",
    "mtr",
    color="children",
    animation_frame="adults",
    labels=LABELS,
    title="Marginal tax rate for a Pennsylvania household",
    color_discrete_map=COLOR_MAP,
)
fig.update_layout(
    xaxis_tickformat="$,",
    yaxis_tickformat=".1%",
    yaxis_range=[0, 0.6],
    plot_bgcolor="white",
    xaxis_gridcolor=LIGHT_GRAY,
    yaxis_gridcolor=LIGHT_GRAY,
)
fig.show()

Based on 2020 Current Population Survey, the 2022 Pennsylvania income tax code would have raised $13.4 billion.

This falls 26% below Pennsylvania’s Independent Fiscal Office’s June 2022 estimate of $18.1 billion in personal income tax revenue for FY2021, and 14% below their June 2021 estimate of $15.5 billion.

from policyengine_us import Microsimulation

ms = Microsimulation(dataset_year=2020)
(ms.calc("pa_income_tax", period=2022).sum() / 1e6).round()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[3], line 3
      1 from policyengine_us import Microsimulation
----> 3 ms = Microsimulation(dataset_year=2020)
      4 (ms.calc("pa_income_tax", period=2022).sum() / 1e6).round()

File ~/work/policyengine-us/policyengine-us/policyengine_us/system.py:115, in Microsimulation.__init__(self, *args, **kwargs)
    114 def __init__(self, *args, **kwargs):
--> 115     super().__init__(*args, **kwargs)
    117     reform = create_structural_reforms_from_parameters(
    118         self.tax_benefit_system.parameters, year_start
    119     )
    120     if reform is not None:

TypeError: __init__() got an unexpected keyword argument 'dataset_year'