Axes are a great option to define at the simulation declaration in order to make a variable v evolves in a given interval.
We'll show this opportunity with the illustration of the evolution of average rate and marginal rate of the French Income Tax.
We import essential modules and initialize the tax and benefit system
%matplotlib inline
import matplotlib.pyplot as plt
from openfisca_france import FranceTaxBenefitSystem
from openfisca_france.scenarios import init_single_entity
tax_benefit_system = FranceTaxBenefitSystem() # Create an instance of French Tax and Benefit system
Let's observe how to declare a simulation with an income (salaire_de_base
) evolving between 0 euros and 100000 euros per year.
scenario = init_single_entity(
tax_benefit_system.new_scenario(),
# Axe declaration
axes = [[
dict( # in a dictionary
count = 100, # 'count' : indicates the number of step
min = 0,
max = 100000,
name = 'salaire_de_base', # the variable you want to make evolve
),
]],
period = 2014,
parent1 = dict(
date_naissance = '1980-01-01',
)
)
simulation = scenario.new_simulation()
simulation.calculate_add('salaire_de_base', 2014)
array([ 0. , 1010.10114, 2020.2023 , 3030.3027 , 4040.4045 , 5050.5054 , 6060.6055 , 7070.707 , 8080.809 , 9090.909 , 10101.011 , 11111.11 , 12121.211 , 13131.315 , 14141.414 , 15151.515 , 16161.618 , 17171.717 , 18181.818 , 19191.918 , 20202.021 , 21212.121 , 22222.22 , 23232.326 , 24242.422 , 25252.525 , 26262.63 , 27272.725 , 28282.828 , 29292.932 , 30303.03 , 31313.13 , 32323.236 , 33333.332 , 34343.434 , 35353.54 , 36363.637 , 37373.74 , 38383.836 , 39393.938 , 40404.043 , 41414.14 , 42424.242 , 43434.344 , 44444.44 , 45454.547 , 46464.652 , 47474.75 , 48484.844 , 49494.94 , 50505.05 , 51515.152 , 52525.26 , 53535.363 , 54545.45 , 55555.55 , 56565.656 , 57575.76 , 58585.863 , 59595.953 , 60606.06 , 61616.16 , 62626.26 , 63636.37 , 64646.473 , 65656.555 , 66666.664 , 67676.766 , 68686.87 , 69696.98 , 70707.08 , 71717.164 , 72727.27 , 73737.375 , 74747.48 , 75757.586 , 76767.67 , 77777.78 , 78787.875 , 79797.97 , 80808.086 , 81818.164 , 82828.28 , 83838.38 , 84848.484 , 85858.586 , 86868.69 , 87878.805 , 88888.88 , 89899. , 90909.09 , 91919.19 , 92929.305 , 93939.38 , 94949.5 , 95959.59 , 96969.69 , 97979.805 , 98989.88 , 100000.01 ], dtype=float32)
income_tax = - simulation.calculate('irpp', 2014)
gross_wage = simulation.calculate_add('salaire_de_base', 2014)
taxable_income = simulation.calculate_add('salaire_imposable', 2014)
plt.plot(gross_wage,income_tax)
plt.ylabel(u"Tax Income")
plt.xlabel(u"Gross Wage")
Text(0.5, 0, 'Gross Wage')
NB : The Income Tax is flat in opposite to common opinion.
average_rate = income_tax / gross_wage
# the 1st value of gross_wage is zero, so there's a warning
/usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:1: RuntimeWarning: invalid value encountered in true_divide """Entry point for launching an IPython kernel.
plt.plot(gross_wage, average_rate)
plt.ylabel("Averate Tax Rate")
plt.xlabel("Gross Wage")
Text(0.5, 0, 'Gross Wage')
marginal_rate = (income_tax[:-1] - income_tax[1:]) / (taxable_income[:-1] - taxable_income[1:] )
plt.plot(gross_wage[:-1], marginal_rate)
plt.ylabel("Marginal Tax Rate")
plt.xlabel("Gross Wage")
Text(0.5, 0, 'Gross Wage')
marginal_rate[25], marginal_rate[90]
(0.1259707, 0.26955944)
We can see the step in the French Tax scale of 14% and 30% (applied after a 10% deduction on the taxable income)
Marginal and Average rate exist as functions implemented in OpenFisca. You can apply them on several income concept
from openfisca_core.rates import average_rate, marginal_rate
csg = simulation.calculate_add('csg', period = 2014)
csg
array([ 0. , -74.434586, -148.86015 , -223.29471 , -297.7293 , -372.15488 , -446.58942 , -521.024 , -595.4586 , -669.8843 , -744.3187 , -818.7533 , -893.17883 , -967.61346 , -1042.048 , -1116.4736 , -1190.9083 , -1265.3428 , -1339.7686 , -1414.203 , -1488.6375 , -1563.072 , -1637.4978 , -1711.9324 , -1786.367 , -1860.7925 , -1935.2269 , -2009.6617 , -2084.0872 , -2158.5217 , -2232.9565 , -2307.3813 , -2381.8167 , -2456.2505 , -2530.6855 , -2605.1108 , -2679.5457 , -2753.9802 , -2828.406 , -2902.84 , -2977.275 , -3051.7007 , -3126.1353 , -3200.5698 , -3275.0044 , -3349.4302 , -3423.8647 , -3498.2988 , -3572.724 , -3647.1592 , -3721.5942 , -3796.019 , -3870.4539 , -3944.8887 , -4019.3145 , -4093.7483 , -4168.183 , -4242.618 , -4317.0435 , -4391.4775 , -4465.913 , -4540.339 , -4614.773 , -4689.2065 , -4763.6333 , -4838.0674 , -4912.501 , -4986.9272 , -5061.3623 , -5135.797 , -5210.2305 , -5284.657 , -5359.0913 , -5433.5264 , -5507.951 , -5582.386 , -5656.821 , -5731.247 , -5805.68 , -5880.1157 , -5954.541 , -6028.975 , -6103.4097 , -6177.8447 , -6252.2705 , -6326.7046 , -6401.1396 , -6475.5654 , -6550. , -6624.4346 , -6698.8604 , -6773.295 , -6847.7295 , -6922.163 , -6996.589 , -7071.024 , -7145.458 , -7219.884 , -7294.3184 , -7368.753 ], dtype=float32)
1 - average_rate(-csg[1:], gross_wage[1:])
array([0.07369024, 0.07368577, 0.07368726, 0.07368797, 0.07368666, 0.07368726, 0.07368767, 0.07368797, 0.07368726, 0.07368755, 0.07368779, 0.07368726, 0.07368749, 0.07368767, 0.07368726, 0.07368743, 0.07368761, 0.07368726, 0.07368743, 0.07368755, 0.07368767, 0.07368743, 0.07368749, 0.07368767, 0.07368737, 0.07368749, 0.07368761, 0.07368737, 0.07368743, 0.07368755, 0.07368731, 0.07368743, 0.07368749, 0.07368761, 0.07368743, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368755, 0.07368761, 0.07368743, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368755, 0.07368755, 0.07368743, 0.07368749, 0.07368755, 0.07368749, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368749, 0.07368743, 0.07368749, 0.07368749, 0.07368755, 0.07368749, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368749, 0.07368755, 0.07368749, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368755, 0.07368743, 0.07368749, 0.07368749, 0.07368755, 0.07368749, 0.07368749, 0.07368755, 0.07368749, 0.07368749, 0.07368755], dtype=float32)
plt.ylim(0,0.1)
plt.plot(gross_wage[1:], 1-average_rate(-csg[1:], gross_wage[1:]))
[<matplotlib.lines.Line2D at 0x7f7c5d2c27d0>]