This notebook contains an example for how to use the taxbrain python package

# # Install conda, taxbrain, and taxcalc if in Google Colab.
import sys
if 'google.colab' in sys.modules and 'taxbrain' not in sys.modules:
    # Install taxbrain and dependencies
    !pip install taxbrain &> /dev/null
    !pip install taxcalc &> /dev/null
    !pip install pypandoc &> /dev/null
    !pip install -U pandas &> /dev/null  # make sure pandas is up to date
from taxbrain import TaxBrain, differences_plot, distribution_plot
reform_url = "https://raw.githubusercontent.com/PSLmodels/Tax-Calculator/master/taxcalc/reforms/Larson2019.json"
start_year = 2021
end_year = 2030

Static Reform#

After importing the TaxBrain class from the taxbrain package, we initiate an instance of the class by specifying the start and end year of the anlaysis, which microdata to use, and a policy reform. Additional arguments can be used to specify econoimc assumptions and individual behavioral elasticites.

Once the class has been initiated, the run() method will handle executing each model

tb_static = TaxBrain(start_year, end_year, microdata="CPS", reform=reform_url)
tb_static.run()
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
File /usr/share/miniconda/envs/taxbrain-dev/lib/python3.12/site-packages/numba/core/serialize.py:30, in _numba_unpickle(address, bytedata, hashed)
     27 _unpickled_memo = {}
---> 30 def _numba_unpickle(address, bytedata, hashed):
     31     """Used by `numba_unpickle` from _helperlib.c
     32 
     33     Parameters
   (...)
     42         unpickled object
     43     """

KeyboardInterrupt: 

The above exception was the direct cause of the following exception:

SystemError                               Traceback (most recent call last)
Cell In[4], line 2
      1 tb_static = TaxBrain(start_year, end_year, microdata="CPS", reform=reform_url)
----> 2 tb_static.run()

File ~/work/Tax-Brain/Tax-Brain/taxbrain/taxbrain.py:178, in TaxBrain.run(self, varlist, client, num_workers)
    176         if self.verbose:
    177             print("Running static simulations")
--> 178         self._static_run(
    179             varlist, base_calc, reform_calc, client, num_workers
    180         )
    181     del base_calc, reform_calc
    183 setattr(self, "has_run", True)

File ~/work/Tax-Brain/Tax-Brain/taxbrain/taxbrain.py:440, in TaxBrain._static_run(self, varlist, base_calc, reform_calc, client, num_workers)
    434 lazy_values = []
    435 for yr in range(self.start_year, self.end_year + 1):
    436     lazy_values.extend(
    437         [
    438             delayed(self._taxcalc_advance(base_calc, varlist, yr)),
    439             delayed(
--> 440                 self._taxcalc_advance(
    441                     reform_calc, varlist, yr, reform=True
    442                 )
    443             ),
    444         ]
    445     )
    446 if client:
    447     futures = client.compute(lazy_values, num_workers=num_workers)

File ~/work/Tax-Brain/Tax-Brain/taxbrain/taxbrain.py:392, in TaxBrain._taxcalc_advance(self, calc, varlist, year, reform)
    384     if reform:
    385         calc = dist_corp(
    386             calc,
    387             self.corp_revenue,
   (...)
    390             self.ci_params,
    391         )
--> 392 calc.calc_all()
    393 df = calc.dataframe(varlist)
    395 return df

File /usr/share/miniconda/envs/taxbrain-dev/lib/python3.12/site-packages/taxcalc/calculator.py:172, in Calculator.calc_all(self, zero_out_calc_vars)
    170 UBI(self.__policy, self.__records)
    171 BenefitPrograms(self)
--> 172 self._calc_one_year(zero_out_calc_vars)
    173 BenefitSurtax(self)
    174 BenefitLimitation(self)

File /usr/share/miniconda/envs/taxbrain-dev/lib/python3.12/site-packages/taxcalc/calculator.py:1435, in Calculator._calc_one_year(self, zero_out_calc_vars)
   1433 del item_cvar
   1434 # Calculate taxes with optimal itemized deduction
-> 1435 self._taxinc_to_amt()
   1436 F2441(self.__policy, self.__records)
   1437 EITC(self.__policy, self.__records)

File /usr/share/miniconda/envs/taxbrain-dev/lib/python3.12/site-packages/taxcalc/calculator.py:1365, in Calculator._taxinc_to_amt(self)
   1361 """
   1362 Call TaxInc through AMT functions.
   1363 """
   1364 TaxInc(self.__policy, self.__records)
-> 1365 SchXYZTax(self.__policy, self.__records)
   1366 GainsTax(self.__policy, self.__records)
   1367 AGIsurtax(self.__policy, self.__records)

File /usr/share/miniconda/envs/taxbrain-dev/lib/python3.12/site-packages/taxcalc/decorators.py:325, in iterate_jit.<locals>.make_wrapper.<locals>.wrapper(*args, **kwargs)
    322 eval(func_code,  # pylint: disable=eval-used
    323      {"applied_f": applied_jitted_f}, fakeglobals)
    324 high_level_fn = fakeglobals['hl_func']
--> 325 ans = high_level_fn(*args, **kwargs)
    326 return ans

File <string>:12, in hl_func(pm, pf)

SystemError: CPUDispatcher(<function ap_func at 0x7f3ebcc29bc0>) returned a result with an exception set

Once the calculators have been run, you can produce a number of tables, including a weighted total of a given variable each year under both current law and the user reform.

print("Combined Tax Liability Over the Budget Window")
tb_static.weighted_totals("combined")
Combined Tax Liability Over the Budget Window
2021 2022 2023 2024 2025 2026 2027 2028 2029 2030
Base 2.269727e+12 3.067767e+12 3.246623e+12 3.395728e+12 3.575938e+12 3.979716e+12 4.161639e+12 4.344151e+12 4.543397e+12 4.749701e+12
Reform 2.326818e+12 3.145972e+12 3.342312e+12 3.509844e+12 3.710034e+12 4.126726e+12 4.329940e+12 4.534780e+12 4.744452e+12 4.961574e+12
Difference 5.709077e+10 7.820500e+10 9.568834e+10 1.141166e+11 1.340957e+11 1.470099e+11 1.683013e+11 1.906291e+11 2.010544e+11 2.118730e+11

If you are interested in a detailed look on the reform’s effect, you can produce a differences table for a given year.

print("Differences Table")
tb_static.differences_table(start_year, "weighted_deciles", "combined")
Differences Table
count tax_cut perc_cut tax_inc perc_inc mean tot_change share_of_change ubi benefit_cost_total benefit_value_total pc_aftertaxinc
0-10n 0.102049 0.000000 0.000000 0.035165 34.458500 8.218450 0.000839 0.001469 0.0 0.0 0.0 0.006305
0-10z 8.390627 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.0 0.0 0.000000
0-10p 12.214010 0.000000 0.000000 5.510201 45.113777 3.693062 0.045107 0.079009 0.0 0.0 0.0 -0.030271
10-20 20.708304 0.000000 0.000000 15.031974 72.589110 17.199769 0.356178 0.623880 0.0 0.0 0.0 -0.049703
20-30 20.706921 0.019010 0.091803 13.230015 63.891753 27.008003 0.559253 0.979585 0.0 0.0 0.0 -0.047439
30-40 20.707534 0.259493 1.253135 11.850040 57.225744 29.340367 0.607567 1.064212 0.0 0.0 0.0 -0.036801
40-50 20.706181 1.020739 4.929636 12.904516 62.322051 27.887624 0.577446 1.011453 0.0 0.0 0.0 -0.014320
50-60 20.708634 2.983512 14.407092 12.853635 62.068967 -36.541184 -0.756718 -1.325465 0.0 0.0 0.0 0.110734
60-70 20.707540 3.810788 18.402900 12.691879 61.291099 -155.091891 -3.211572 -5.625378 0.0 0.0 0.0 0.261506
70-80 20.705701 4.042144 19.521890 13.340665 64.429912 -198.758187 -4.115428 -7.208569 0.0 0.0 0.0 0.271550
80-90 20.709850 4.418265 21.334121 14.297969 69.039464 -427.711584 -8.857843 -15.515367 0.0 0.0 0.0 0.416827
90-100 20.708024 1.431391 6.912254 17.352383 83.795459 3471.405278 71.885943 125.915170 0.0 0.0 0.0 -1.292653
ALL 207.075375 17.985342 8.685408 129.098443 62.343696 275.700439 57.090772 100.000000 0.0 0.0 0.0 -0.321387
90-95 10.354203 1.292340 12.481311 8.241434 79.595059 -298.772462 -3.093551 -5.418653 0.0 0.0 0.0 0.256932
95-99 8.282277 0.139051 1.678898 7.283324 87.938673 318.774347 2.640177 4.624526 0.0 0.0 0.0 -0.070544
Top 1% 2.071544 0.000000 0.000000 1.827625 88.225265 34920.477840 72.339316 126.709297 0.0 0.0 0.0 -4.338110

TaxBrain comes with two (and counting) built in plots as well

differences_plot(tb_static, 'combined', figsize=(10, 8));
../../_images/5df99c44f72b5e38d684739ee82669a14997e5eb9e9eeae13ef8eee355c8b971.png
distribution_plot(tb_static, 2021, figsize=(10, 8));
../../_images/03d12c7f1175d816c18609e34c88ec90342a5ea9dadac5b34725f9ddcc3d395c.png

You can run a partial-equlibrium dynamic simulation by initiating the TaxBrian instance exactly as you would for the static reform, but with your behavioral assumptions specified

tb_dynamic = TaxBrain(start_year, end_year, microdata="CPS", reform=reform_url,
                      behavior={"sub": 0.25})
tb_dynamic.run()

Once that finishes running, we can produce the same weighted total table as we did with the static run.

print("Partial Equilibrium - Combined Tax Liability")
tb_dynamic.weighted_totals("combined")
Partial Equilibrium - Combined Tax Liability
2021 2022 2023 2024 2025 2026 2027 2028 2029 2030
Base 2.269727e+12 3.067767e+12 3.246623e+12 3.395728e+12 3.575938e+12 3.979716e+12 4.161639e+12 4.344151e+12 4.543397e+12 4.749701e+12
Reform 2.307804e+12 3.119395e+12 3.312243e+12 3.476774e+12 3.673491e+12 4.082934e+12 4.282357e+12 4.483171e+12 4.690507e+12 4.904587e+12
Difference 3.807725e+10 5.162814e+10 6.561941e+10 8.104634e+10 9.755272e+10 1.032176e+11 1.207186e+11 1.390202e+11 1.471100e+11 1.548863e+11

Or we can produce a distribution table to see details on the effects of the reform.

print("Distribution Table")
tb_dynamic.distribution_table(start_year, "weighted_deciles", "expanded_income", "reform")
Distribution Table
count c00100 count_StandardDed standard count_ItemDed c04470 c04600 c04800 taxbc c62100 ... othertaxes refund iitax payrolltax combined ubi benefit_cost_total benefit_value_total expanded_income aftertax_income
0-10n 0.102049 -7.647952 0.018507 -5.835622 0.000000 0.000000 0.0 0.000000 0.000000 -7.764826 ... 0.000000 0.354646 -0.354646 0.064998 -0.289648 0.0 0.799655 0.799655 -6.940854 -6.651206
0-10z 8.391348 -0.092134 8.391348 112.514735 0.000000 0.000000 0.0 0.000000 0.000000 -0.092134 ... 0.000000 17.779859 -17.779859 0.000000 -17.779859 0.0 0.000000 0.000000 0.000000 17.779859
0-10p 12.213289 28.286909 12.207105 167.047672 0.006184 0.035899 0.0 0.109175 0.003643 28.250938 ... 0.000000 28.404318 -28.400675 3.495389 -24.905286 0.0 19.592770 19.592770 50.389807 75.295093
10-20 20.707972 207.041657 20.230779 280.157298 0.472337 7.619006 0.0 25.986559 2.401345 200.049307 ... 0.000000 68.924569 -66.523628 27.626076 -38.897552 0.0 107.290602 107.290602 323.220845 362.118396
20-30 20.707385 316.378323 19.648591 287.017567 1.053396 18.740597 0.0 116.225685 11.584224 299.238036 ... 0.000000 67.787144 -56.195886 43.577393 -12.618493 0.0 258.441980 258.441980 590.805721 603.424214
30-40 20.707088 392.642544 19.510973 297.416383 1.187950 22.114507 0.0 184.988094 19.315954 371.147034 ... 0.000000 67.101813 -47.772787 53.603619 5.830832 0.0 369.313918 369.313918 787.711190 781.880357
40-50 20.708472 550.480439 19.029242 307.522806 1.676905 33.455448 0.0 286.992712 30.516102 519.344714 ... 0.000000 78.292375 -47.767104 72.879144 25.112041 0.0 404.535394 404.535394 994.589197 969.477157
50-60 20.707393 735.630028 18.331876 326.411031 2.373124 49.426182 0.0 425.521954 47.073700 691.665427 ... 0.000000 93.114874 -46.034925 95.833407 49.798482 0.0 466.945896 466.945896 1258.080439 1208.281958
60-70 20.707515 959.511949 17.811997 357.787922 2.893239 62.644720 0.0 606.027111 72.245168 905.890709 ... 0.000000 112.380798 -40.126138 122.146512 82.020374 0.0 578.376040 578.376040 1603.049167 1521.028793
70-80 20.707197 1365.708941 16.719155 373.852288 3.982463 98.050853 0.0 941.858952 119.044547 1288.034856 ... 0.000000 121.724695 -2.658703 172.536431 169.877728 0.0 634.000703 634.000703 2085.339711 1915.461983
80-90 20.707626 2093.482677 14.553142 349.813909 6.152092 179.989249 0.0 1578.829459 218.697073 1951.769562 ... 0.004426 125.344051 93.372100 257.189635 350.561734 0.0 640.771616 640.771616 2872.252958 2521.691223
90-100 20.708041 6246.236344 9.453390 234.654561 11.254651 386.830268 0.0 5608.201771 1197.758029 5942.795098 ... 13.805670 47.686797 1165.232430 553.861208 1719.093638 0.0 512.904614 512.904614 6987.435086 5268.341448
ALL 207.075375 12887.659726 175.906106 3088.360551 31.052341 858.906729 0.0 9774.741472 1718.639786 12190.328720 ... 13.810095 828.895941 904.990179 1402.813813 2307.803992 0.0 3992.973188 3992.973188 17545.933268 15238.129276
90-95 10.353704 1667.324398 5.676570 140.884353 4.677134 148.216845 0.0 1374.670598 220.454555 1553.995778 ... 0.030698 34.014434 186.471142 189.172816 375.643958 0.0 284.797859 284.797859 2039.255590 1663.611631
95-99 8.283571 2341.021395 3.296412 82.219564 4.987159 170.622619 0.0 2075.284086 397.064195 2203.591113 ... 1.300444 13.626819 384.737819 212.266995 597.004815 0.0 192.019886 192.019886 2627.393087 2030.388273
Top 1% 2.070766 2237.890550 0.480409 11.550644 1.590357 67.990803 0.0 2158.247087 580.239279 2185.208206 ... 12.474527 0.045543 594.023468 152.421397 746.444865 0.0 36.086868 36.086868 2320.786409 1574.341544

16 rows × 24 columns

Dynamic Reform with Corporate Income Tax Incidence#

Now we simulate a dynamic revenue estimate while accounting for the incidence of a corporate income tax change.

# Corporate revenue estimate
corp_rev = [5_000_000_000] * (end_year - start_year + 1)
incidence_assumptions = {
    "Incidence": {  # long-run incidence of corporate tax
        "Labor share": 0.5,
        "Shareholder share": 0.4,
        "All capital share": 0.1,
    },
    "Long run years": 10,  # number of years to reach long-run incidence
}
tb_dynamic = TaxBrain(start_year, end_year, microdata="CPS", reform=reform_url,
                      behavior={"sub": 0.25},
                      corp_revenue=corp_rev,
                      corp_incidence_assumptions=incidence_assumptions)
tb_dynamic.run()
print("Partial Equilibrium - Combined Tax Liability")
tb_dynamic.weighted_totals("combined")
Partial Equilibrium - Combined Tax Liability
2021 2022 2023 2024 2025 2026 2027 2028 2029 2030
Base 2.269727e+12 3.067767e+12 3.246623e+12 3.395728e+12 3.575938e+12 3.979716e+12 4.161639e+12 4.344151e+12 4.543397e+12 4.749701e+12
Reform 2.309448e+12 3.121009e+12 3.313788e+12 3.478349e+12 3.675071e+12 4.084663e+12 4.284063e+12 4.484873e+12 4.692225e+12 4.906309e+12
Difference 3.972134e+10 5.324191e+10 6.716455e+10 8.262134e+10 9.913307e+10 1.049468e+11 1.224239e+11 1.407223e+11 1.488282e+11 1.566081e+11