Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
| Download

📚 The CoCalc Library - books, templates and other resources

Views: 96159
License: OTHER
Kernel: SageMath 8.6

The effect of the introduction of a proportional tax on a commodity - A partial equilibrium analysis under perfect competition

Notebook for the Public Finance course, UCSC, AY 2018/2019 by Duccio Gamannossi degl' Innocenti. You can find more information on the course here.

The market equilibrium with no taxes

Defining the demand function as

demand(a, b, P) = ((a/b) - ((1/b)*P)) html("Q^D="+latex(demand(a, b, P)))

Where a,b>0a, b >0 and 0Pa0 \leq P \leq a to ensure positivity of quantity demanded and the negative slope of the curve

Then, the inverse demand function is:

demand_inv(a, b, Q) = solve(demand(a, b, P) == Q, P)[0].rhs() html("P^D="+latex(demand_inv(a, b, Q)))

with 0Qab0 \leq Q \leq \frac{a}{b} to ensure positivity of price.

Given a continum of identical firms with individual marginal cost function Cmar=dqi+c;c,d>0C_{mar}= dq_i+c; c,d>0 the (inverse) aggregate supply curve is:

supply_inv(c, d, Q) = c + (d*Q) html("P^S="+latex(supply_inv(c, d, Q)))

and its inverse, the aggregate supply, is:

supply(c, d, P) = solve(supply_inv(c, d, Q) == P, Q)[0].rhs() html("Q^S="+latex(supply(c, d, P)))

The market equilibrium is (Q,P)(Q^*, P^*), where QQ^* is such that inverse demand equates inverse supply PD=PSP^D = P^S

eq_Q(a, b, c, d) = solve(demand_inv==supply_inv, Q)[0].rhs() html("Q^*="+latex(eq_Q(a, b, c, d)))

And PP^* such that the demand is equal to inverse supply, QD=QSQ^D = Q^S

eq_P(a, b, c, d) = solve(demand == supply, P)[0].rhs() html("P^*="+latex(eq_P(a, b, c, d)))

The impact of demand and supply elasticity on market equilibrium

Varying the values of the parameters a,b,c,da, b, c, d, leads to different equilibrium outcomes. If we assume a=10,c=.01a=10, c =.01 we can investigate how varying the slope of the demand and supply lines impacts on the market equilibrium. Note that a smaller bb will result in a more elastic demand and that a smaller dd will result in a more elastic supply. Graphically:

from sage.repl.ipython_kernel.interact import interact import matplotlib as mpl mpl.rcParams['axes.labelsize'] = 14. mpl.rcParams['xtick.labelsize'] = 14. mpl.rcParams['ytick.labelsize'] = 14. mpl.rcParams['legend.fontsize'] = 14. mpl.rcParams['figure.titlesize'] = 50. mpl.rcParams['font.size'] = 14. mpl.rcParams['font.family'] = 'serif' verticalPad(a, b) = demand_inv(a, b, 0)*(1/10) pmax(a, b) = demand_inv(a, b, 0) + verticalPad qmax(a, b) = a/b consumer_color = Color(.098, .447, .82) producer_color = Color(.588, .204, .518)
a=10 c=.01 @interact def _(b = slider(.0001, 5, step_size=.11, default = .5), d = slider(.0001, 5, step_size=.11, default = .5), zoom = True): consumer_surplus_plot = polygon2d([[eq_Q(a, b, c, d), eq_P(a, b, c, d)], [0, eq_P(a, b, c, d)], [0, a]], rgbcolor=consumer_color, alpha=.6, legend_label = 'consumer surplus') producer_surplus_plot = polygon2d([[eq_Q(a, b, c, d), eq_P(a, b, c, d)], [0, eq_P(a, b, c, d)], [0, c]], rgbcolor = producer_color, alpha = .6, legend_label = 'producer surplus') supply_plot = plot(supply_inv(c, d, Q), (Q, 0, qmax(a, b)), linestyle = ('-'), rgbcolor = (producer_color), legend_label = 'supply') demand_plot = plot(demand_inv(a, b, Q), (Q, 0, qmax(a, b)), linestyle = ('-'), rgbcolor = (consumer_color), legend_label = 'demand', axes_labels=['quantity','price'], ticks = [[eq_Q(a, b, c, d)], [eq_P(a, b, c, d)]], tick_formatter=[["$Q^*_{no-tax}$"], ["$P^*_{no-tax}$"]], axes_labels_size = 1, title = "No tax" ) dot = point((eq_Q(a, b, c, d), eq_P(a, b, c, d)), pointsize=60, rgbcolor=(0,0,0)) P_tot = dot + demand_plot + consumer_surplus_plot + supply_plot + producer_surplus_plot P_tot.set_legend_options(handlelength=2, borderaxespad = 0, labelspacing =.05, bbox_to_anchor=(1.05, 1), loc=2) P_tot.fontsize(14) show(P_tot, ymin = -verticalPad(a, b), ymax = pmax(a, b), xmin = -1, xmax = (a + a/10) if zoom == True else qmax(a, b) if qmax(a, b) < 20 else 20, figsize = 7)

Proportional tax statutorely levied on producers

Now suppose to introduce a proportional tax t>0t>0 statutorily levied on producers (so, the aggregate demand curve is unaffected). This increases the marginal cost for the producers Cmar=(dqi+c)(1+t)C_{mar}= (dq_i+c)(1+t) leading to a shift upward of the aggregate (inverse) supply curve that becomes:

supply_inv_tax(c, d, Q, t) = supply_inv(c, d, Q) * (1+t) html("P^S_{tax}="+latex(supply_inv_tax(c, d, Q, t)))

Giving a supply function in presence of proportional tax:

supply_tax(c, d, P, t) = solve(supply_inv_tax(c, d, Q, t) == P, Q)[0].rhs() html("Q^S_{tax}="+latex(supply_tax(c, d, P, t)))

The new equilibrium (Qtaxprod,Ptaxprod)(Q^*_{tax-prod}, P^*_{tax-prod}) is then:

eq_Q_tax_prod(a, b, c, d, t) = solve(demand_inv==supply_inv_tax, Q)[0].rhs() html("Q^*_{tax-prod.}="+latex(eq_Q_tax_prod(a, b, c, d, t)))
eq_P_tax_prod(a, b, c, d, t) = solve(demand == supply_tax, P)[0].rhs() html("P^*_{tax-prod.}="+latex(eq_P_tax_prod(a, b, c, d, t)))

Graphically:

verticalPad(a, b) = demand_inv(a, b, 0)*(1/10) pmax(a, b) = demand_inv(a, b, 0) + verticalPad qmax(a, b) = a/b consumer_color = Color(.098, .447, .82) producer_color = Color(.588, .204, .518) a=10 c=.01 @interact def _(b = slider(.0001, 5, step_size=.11, default = .5), d = slider(.0001, 5, step_size=.11, default = .5), t = slider(0, 10, step_size=.05, default = 3), zoom = True): consumer_surplus_plot_tax_prod= polygon2d([[eq_Q_tax_prod(a, b, c, d, t), demand_inv(a, b, eq_Q_tax_prod(a, b, c, d, t))], [0, demand_inv(a, b, eq_Q_tax_prod(a, b, c, d, t))], [0, a]], rgbcolor=consumer_color, alpha=.6, legend_label = 'surplus - consumers') producer_surplus_plot_tax_prod = polygon2d([[eq_Q_tax_prod(a, b, c, d, t), supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))], [0, supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))], [0, c]], rgbcolor = producer_color, alpha = .6, legend_label = 'surplus - producers') deadweight_loss_consumer_plot_tax_prod = polygon2d([[eq_Q(a, b, c, d), eq_P(a, b, c, d, t)], [eq_Q_tax_prod(a, b, c, d, t), eq_P_tax_prod(a, b, c, d, t)], [eq_Q_tax_prod(a, b, c, d, t), eq_P(a, b, c, d, t)]], rgbcolor = consumer_color, alpha = .2, legend_label = 'deadweight loss - consumers') deadweight_loss_producer_plot_tax_prod = polygon2d([[eq_Q(a, b, c, d), eq_P(a, b, c, d)], [eq_Q_tax_prod(a, b, c, d, t), eq_P(a, b, c, d)], [eq_Q_tax_prod(a, b, c, d, t), supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))]], rgbcolor = producer_color, alpha = .2, legend_label = 'deadweight loss - producers') tax_rev_consumer_plot_tax_prod = polygon2d([[eq_Q_tax_prod(a, b, c, d, t), eq_P(a, b, c, d)], [0, eq_P(a, b, c, d)], [0, eq_P_tax_prod(a, b, c, d, t)], [eq_Q_tax_prod(a, b, c, d, t), eq_P_tax_prod(a, b, c, d, t)]], rgbcolor = consumer_color, alpha = .9, legend_label = 'tax revenues - consumers') tax_rev_producer_plot_tax_prod = polygon2d([[eq_Q_tax_prod(a, b, c, d, t), eq_P(a, b, c, d)], [0, eq_P(a, b, c, d)], [0, supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))], [eq_Q_tax_prod(a, b, c, d, t), supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))]], rgbcolor = producer_color, alpha = .9, legend_label = 'tax revenues - producers') supply_plot_tax_prod = plot(supply_inv(c, d, Q), (Q, 0, qmax(a, b)), linestyle = ('-'), rgbcolor = (producer_color), legend_label = 'supply') supply_tax_plot_tax_prod = plot(supply_inv_tax(c, d, Q, t), (Q, 0, qmax(a, b)), linestyle = ('--'), rgbcolor = (producer_color), legend_label = 'supply - proportional tax', axes_labels=['quantity','price'], ticks = [[eq_Q(a, b, c, d)] if t == 0 else [eq_Q(a, b, c, d), eq_Q_tax_prod(a, b, c, d, t)], [eq_P(a, b, c, d)] if t == 0 else [eq_P(a, b, c, d), supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t)), eq_P_tax_prod(a, b, c, d, t)]], tick_formatter=[["$Q^*_{no-tax}$"] if t == 0 else ["$Q^*_{no-tax}$", "$Q^*_{tax-prod.}$"], ["$P^*_{no-tax}$"] if t == 0 else ["$P^*_{no-tax}$", "$P^*_{seller, tax-prod.}$", "$P^*_{buyer, tax-prod.}$"]], axes_labels_size = 1, title = "Proportional tax - Producer" ) demand_plot_tax_prod = plot(demand_inv(a, b, Q), (Q, 0, qmax(a, b)), linestyle = ('-'), rgbcolor = (consumer_color), legend_label = 'demand', ) dot = point((eq_Q(a, b, c, d), eq_P(a, b, c, d)), pointsize=60, rgbcolor=(0,0,0) if t == 0 else (.4, .4, .4)) dot_tax_prod = point([(eq_Q_tax_prod(a, b, c, d, t), eq_P_tax_prod(a, b, c, d,t ))] if t > 0 else [], pointsize=60, rgbcolor=(.4, .4, .4)) P_tot_tax_prod = demand_plot_tax_prod + consumer_surplus_plot_tax_prod + tax_rev_consumer_plot_tax_prod + deadweight_loss_consumer_plot_tax_prod + supply_plot_tax_prod + supply_tax_plot_tax_prod + producer_surplus_plot_tax_prod + tax_rev_producer_plot_tax_prod + deadweight_loss_producer_plot_tax_prod + dot + dot_tax_prod P_tot_tax_prod.set_legend_options(handlelength=2, borderaxespad = 0, labelspacing =.05, bbox_to_anchor=(1.05, 1), loc=2) P_tot_tax_prod.fontsize(14) show(P_tot_tax_prod, ymin = -verticalPad(a, b), ymax = pmax(a, b), xmin = -1, xmax = (a + a/10) if zoom == True else qmax(a, b) if qmax(a, b) < 20 else 20, figsize = 7)

Market equilibrium in presence of proportional tax on producers

It is easy to verify that Qnotax>QtaxprodQ^*_{no-tax}>Q^*_{tax-prod} and Pbuyertaxprod<PnotaxP^*_{buyer_{tax-prod}}<P^*_{no-tax} , in particular:

reset("a","c") var('a,c') diff_Q(a, b, c, d, t) = (eq_Q(a, b, c, d) - eq_Q_tax_prod(a, b, c, d, t)) diff_P_buyer(a, b, c, d, t) = (eq_P_tax_prod(a, b, c, d, t) - eq_P(a, b, c, d)) html("Q^*_{no-tax}-Q^*_{tax-prod.}=" + latex(expand(diff_Q(a, b, c, d, t)).simplify_full()) + "\\\\ " + "P^*_{buyer_{tax-prod.}}-P^*_{no-tax}=" + latex(expand(diff_P_buyer(a, b, c, d, t)).simplify_full()))

Tax incidence

Equilibrium Price PnotaxP^*_{no-tax}, Equilibrium Price in presence of tax PtaxP^*_{tax}, Buyer Price PbuyerP^*_{buyer}, Seller Price PsellerP^*_{seller}

When no tax is present in a market, the only price relevant to the analysis is the equilibrium price PnotaxP^*_{no-tax}. However, when a tax is introduced, there are two prices of interest:

  • The price paid by the buyer Pbuyer=PtaxP^*_{buyer} = P^*_{tax} that is equal to the market price, the one at which goods are traded. If the tax is levied on the producer, the buyer price is the one where it holds QtaxS=QDQ^S_{tax} = Q^D, that is, the equilibrium price when the supply and demand incorporate the tax.

  • The price received by the seller PsellerP^*_{seller} that can be computed by evaluating the supply at the quantity exchanged in the market PS(Q=Qtaxprod.)P^S(Q=Q_{tax-prod.}^*). In the case of a proportional taxes, the vertical distance PbuyerPsellerP^*_{buyer} - P^*_{seller} is equal to tax tt, so the computation of the seller price is even easier.

Given the wedge in the buyer and seller price imposed by the tax, tax incidence is identified by how much of the variation of price, relative to a setting without taxes, is beared by one side or the other of the market.

Using the no-tax equilibrium price PnotaxP^*_{no-tax}, buyer price PbuyerP^*_{buyer} and seller price PsellerP^*_{seller}, it is possible to compute:

  • tax incidence on consumer: PbuyerPnotaxP^*_{buyer}-P^*_{no-tax}

  • tax incidence on producer: PnotaxPsellerP^*_{no-tax}-P^*_{seller} .

reset("a","c") var('a,c') diff_P_buyer_P(a, b, c, d, t) = eq_P_tax_prod(a, b, c, d, t) - eq_P(a, b, c, d) diff_P_P_seller(a, b, c, d, t) = (eq_P(a, b, c, d) - supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))) html("P^*_{buyer_{tax-prod.}}-P^*_{no-tax}=" + latex(expand(diff_P_buyer_P(a, b, c, d, t)).simplify_full()) + "\\\\ " + "P^*_{no-tax}-P^*_{seller_{tax-prod.}}=" + latex(expand(diff_P_P_seller(a, b, c, d, t)).simplify_full()))

The characterization of these two quantities allows to analyze the role that the elasticity of demand (decreasing in bb) and the elasticity of supply (decreasing in dd) have on tax shifting and tax incidence.

In a perfectly competitive market the extent of tax shifting depends on the relative elasticities of demand and supply:

  • For a given elasticity of the demand curve: if the supply is very elastic, the tax incidence is mostly on the consumers, if the supply is very inelastic, the tax incidence is mostly on the producers.

  • For a given elasticity of the supply curve: if the demand is very elastic, the tax incidence is mostly on the producers, if the supply is very inelastic, the tax incidence is mostly on the consumers

So, partial tax shifting is observed if the demand and supply curve are not totally elastic or inelastic. Conversely, in these extreme cases it holds:

Furthermore, it can be verified that there are two cases where prices do not increase and the tax burden is completely beared by the producers - no tax shifting taking place:

  • Demand is perfectly elastic, b0b \rightarrow 0

  • Supply is perfectly inelastic, dinfd \rightarrow \inf

Conversely, price increases exactly of an amount equal to tt and the tax burden is completely paid by the consumers - complete tax shifting - if:

  • Demand is perfectly inelastic, binfb \rightarrow \inf

  • Supply is perfectly elastic, d0d \rightarrow 0

Analysis of deadweight loss and tax revenue

Introducing a tax distorts economic decision. A measure of the inefficiency caused by a tax is its deadweight loss, the surplus loss by both sides of the market exceeding the revenues collected. The deadweight loss DLDL is composed by a part beared by the producer DLprod.DL_{prod.}, identified by the polygon [{Qnotax,Pnotax},{Qtaxprod.,Pnotax},{Qtaxprod.,Psellertaxprod.}][\{Q^*_{no-tax}, P^*_{no-tax}\},\{Q^*_{tax-prod.}, P^*_{no-tax}\}, \{Q^*_{tax-prod.}, P^*_{seller_{tax-prod.}}\}], and one beared by the consumer DLcons.DL_{cons.} equal to [{Qnotax,Pnotax},{Qtaxprod.,Pnotax},{Qtaxprod.,Pbuyertaxprod.}][\{Q^*_{no-tax}, P^*_{no-tax}\},\{Q^*_{tax-prod.}, P^*_{no-tax}\}, \{Q^*_{tax-prod.}, P^*_{buyer{tax-prod.}} \}]. To measure the extent of the deadweight loss we proceed to compute the areas of these two triangles.

DL_prod(a, b, c, d, t) = ((eq_Q(a, b, c, d) - eq_Q_tax_prod(a, b, c, d, t)) * (eq_P(a, b, c, d)-supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t)))) /2 DL_cons(a, b, c, d, t) = ((eq_Q(a, b, c, d) - eq_Q_tax_prod(a, b, c, d, t)) * (eq_P_tax_prod(a, b, c, d, t) - eq_P(a, b, c, d))) /2 DL(a, b, c, d, t) = DL_prod + DL_cons html("DL_{prod.}=" + latex(expand(DL_prod).simplify_full()) + "\\\\ " + "DL_{cons.}=" + latex(expand(DL_cons).simplify_full()) + "\\\\ " + "DL=" + latex(expand(DL).simplify_full()))

Tax revenues RR can be computed as the area of the polygon [{Qtaxprod.,Psellertaxprod.},{Qtaxprod.,Pbuyertaxprod.},{0,Pbuyertaxprod.},{0,Psellertaxprod.}][\{ Q^*_{tax-prod.}, P^*_{seller_{tax-prod.}}\}, \{ Q^*_{tax-prod.}, P^*_{buyer_{tax-prod.}}\}, \{0, P^*_{buyer_{tax-prod.}}\}, \{ 0, P^*_{seller_{tax-prod.}}\} ]

R(a, b, c, d, t) = eq_Q_tax_prod(a, b, c, d, t) * (eq_P_tax_prod(a, b, c, d, t) - supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))) html("R=" + latex(expand(R).simplify_full()))

A result that clearly highlights that the deadweight loss:

  • decreases the more inelastic are the demand and supply - a result driving many tax systems to impose commodity taxation on goods characterized by low elasticity of demand.

  • increases non linearly in the tax - it is better to impose small taxes on many goods than heavy taxes on few goods

While revenues

  • decrease the more inelastic are the demand and supply

  • have a non-linear relationship with t, for low walues of tt, increasing tt increases RR while for high values of tt rising taxes leads to lower revenues.

The role of markets in the outcomes of tax policy

The government has the power to impose a tax on whichever side of the market it deems right to. However, the consequences of this action are mediated by the market where the consumers and producers make their economic decisions. The side that is more able to adjust its economic choices in response to price changes (higher elasticity) will be able to shift a bigger part of the tax burden on the other side. More so, imposing a tax on a market with more inelastic demand and/or supply is more efficient but also leads to lower amount of revenues collected.

Proportional tax statutorely levied on consumers, does it make any difference?

If the tax is imposed on consumers, the demand function is defined as PtaxconsD=PD(1+t)=Qb+aP^D_{tax-cons} = P^D (1+t) = -Qb+ a so that it is:

demand_tax_inv(a, b, Q, t) = demand_inv(a, b, Q) / (1+t) demand_tax(a, b, P, t) = solve(demand_tax_inv(a, b, Q, t) == P, Q)[0].rhs() html("Q^D_{tax}=" + latex(demand_tax(a, b, P, t)) + "\\\\ " + "P^D_{tax}=" + latex(demand_tax_inv(a, b, Q, t)))

In this case the market equilibrium is identified by the couple:

eq_Q_tax_cons(a, b, c, d, t) = solve(demand_tax_inv==supply_inv, Q)[0].rhs() eq_P_tax_cons(a, b, c, d, t) = demand_inv(a, b, eq_Q_tax_cons(a, b, c, d, t)) html("(Q_{tax-cons.}^*="+latex(eq_Q_tax_cons(a, b, c, d, t)) + ", P_{tax-cons.}^*="+latex(eq_P_tax_cons(a, b, c, d, t).simplify_full()) + ")")

That we can easily see is exactly equal to the equilibrium identified by the case where the tax is levied on producers

html("(Q_{tax-prod.}^*="+latex(eq_Q_tax_prod(a, b, c, d, t)) + ", P_{tax-prod.}^*="+latex(eq_P_tax_prod(a, b, c, d, t)) + ")")

IMPORTANT NOTE

In the case of a tax levied on producer, the equilibrium price (and buyer price) Ptaxprod=PbuyertaxprodP^*_{tax-prod}= P^*_{buyer_{tax-prod}} is defined by the condition QD=QtaxSQ^D = Q^S_{tax}. However, when considering a tax levied the consumer, the specular condition QtaxD=QSQ^D_{tax} = Q^S identifies the seller price PsellertaxconsP^*_{seller_{tax-cons}}. To compute the equilibrium/buyer price Ptaxcons.=Pbuyertaxcons.P_{tax-cons.}^*= P^*_{buyer_{tax-cons.}} when a tax on consumers is levied, we need to first compute the equilibrium quantity traded in the market Qtaxcons.Q_{tax-cons.}^*, identified by the condition PtaxD=PSP^D_{tax}=P^S, and plug it in the demand function Ptaxcons.=PD(Q=Qtaxcons.)P_{tax-cons.}^* = P^D(Q=Q_{tax-cons.}^*).

P_seller_cons(a, b, c, d, t) = solve(demand_tax==supply, P)[0].rhs() P_buyers_cons(a, b, c, d, t) = demand_inv(a, b, eq_Q_tax_cons(a, b, c, d, t)).simplify_full() html("P^*_{seller_{tax-cons}}="+latex(P_seller_cons(a, b, c, d, t)) + ", P_{buyers_{tax-cons.}}="+latex(P_buyers_cons(a, b, c, d, t)))
verticalPad(a, b) = demand_inv(a, b, 0)*(1/10) pmax(a, b) = demand_inv(a, b, 0) + verticalPad qmax(a, b) = a/b consumer_color = Color(.098, .447, .82) producer_color = Color(.588, .204, .518) a=10 c=.01 @interact def _(b = slider(.0001, 5, step_size=.11, default = .5), d = slider(.0001, 5, step_size=.11, default = .5), t = slider(0, 10, step_size=.05, default = 3), zoom = True): # tax statutorely levied on producers consumer_surplus_plot_tax_prod= polygon2d([[eq_Q_tax_prod(a, b, c, d, t), demand_inv(a, b, eq_Q_tax_prod(a, b, c, d, t))], [0, demand_inv(a, b, eq_Q_tax_prod(a, b, c, d, t))], [0, a]], rgbcolor=consumer_color, alpha=.6, legend_label = 'surplus - consumers') producer_surplus_plot_tax_prod = polygon2d([[eq_Q_tax_prod(a, b, c, d, t), supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))], [0, supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))], [0, c]], rgbcolor = producer_color, alpha = .6, legend_label = 'surplus - producers') deadweight_loss_consumer_plot_tax_prod = polygon2d([[eq_Q(a, b, c, d), eq_P(a, b, c, d, t)], [eq_Q_tax_prod(a, b, c, d, t), eq_P_tax_prod(a, b, c, d, t)], [eq_Q_tax_prod(a, b, c, d, t), eq_P(a, b, c, d, t)]], rgbcolor = consumer_color, alpha = .2, legend_label = 'deadweight loss - consumers') deadweight_loss_producer_plot_tax_prod = polygon2d([[eq_Q(a, b, c, d), eq_P(a, b, c, d)], [eq_Q_tax_prod(a, b, c, d, t), eq_P(a, b, c, d)], [eq_Q_tax_prod(a, b, c, d, t), supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))]], rgbcolor = producer_color, alpha = .2, legend_label = 'deadweight loss - producers') tax_rev_consumer_plot_tax_prod = polygon2d([[eq_Q_tax_prod(a, b, c, d, t), eq_P(a, b, c, d)], [0, eq_P(a, b, c, d)], [0, eq_P_tax_prod(a, b, c, d, t)], [eq_Q_tax_prod(a, b, c, d, t), eq_P_tax_prod(a, b, c, d, t)]], rgbcolor = consumer_color, alpha = .9, legend_label = 'tax revenues - consumers') tax_rev_producer_plot_tax_prod = polygon2d([[eq_Q_tax_prod(a, b, c, d, t), eq_P(a, b, c, d)], [0, eq_P(a, b, c, d)], [0, supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))], [eq_Q_tax_prod(a, b, c, d, t), supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t))]], rgbcolor = producer_color, alpha = .9, legend_label = 'tax revenues - producers') supply_plot_tax_prod = plot(supply_inv(c, d, Q), (Q, 0, qmax(a, b)), linestyle = ('-'), rgbcolor = (producer_color), legend_label = 'supply') supply_tax_plot_tax_prod = plot(supply_inv_tax(c, d, Q, t), (Q, 0, qmax(a, b)), linestyle = ('--'), rgbcolor = (producer_color), legend_label = 'supply - proportional tax', axes_labels=['quantity','price'], ticks = [[eq_Q(a, b, c, d)] if t == 0 else [eq_Q(a, b, c, d), eq_Q_tax_prod(a, b, c, d, t)], [eq_P(a, b, c, d)] if t == 0 else [eq_P(a, b, c, d), supply_inv(c, d, eq_Q_tax_prod(a, b, c, d, t)), eq_P_tax_prod(a, b, c, d, t)]], tick_formatter=[["$Q^*_{no-tax}$"] if t == 0 else ["$Q^*_{no-tax}$", "$Q^*_{tax-prod.}$"], ["$P^*_{no-tax}$"] if t == 0 else ["$P^*_{no-tax}$", "$P^*_{seller, tax-prod.}$", "$P^*_{buyer, tax-prod.}$"]], axes_labels_size = 1, title = "Proportional tax - Producer" ) demand_plot_tax_prod = plot(demand_inv(a, b, Q), (Q, 0, qmax(a, b)), linestyle = ('-'), rgbcolor = (consumer_color), legend_label = 'demand', ) dot_tax_prod = point([(eq_Q_tax_prod(a, b, c, d, t), eq_P_tax_prod(a, b, c, d,t ))] if t > 0 else [], pointsize=60, rgbcolor=(.4, .4, .4)) # tax statutorely levied on consumers consumer_surplus_plot_tax_cons = polygon2d([[eq_Q_tax_cons(a, b, c, d, t), demand_inv(a, b, eq_Q_tax_cons(a, b, c, d, t))], [0, demand_inv(a, b, eq_Q_tax_cons(a, b, c, d, t))], [0, demand_inv(a, b, 0, t)]], rgbcolor=consumer_color, alpha=.6, legend_label = 'surplus - consumers') producer_surplus_plot_tax_cons = polygon2d([[eq_Q_tax_cons(a, b, c, d, t), P_seller_cons(a, b, c, d, t)], [0, P_seller_cons(a, b, c, d, t)], [0, c]], rgbcolor = producer_color, alpha = .6, legend_label = 'surplus - producers') tax_rev_consumer_plot_tax_cons = polygon2d([[eq_Q_tax_cons(a, b, c, d, t), demand_inv(a, b, eq_Q_tax_cons(a, b, c, d, t))], [0, demand_inv(a, b, eq_Q_tax_cons(a, b, c, d, t))], [0, eq_P(a, b, c, d, t)], [eq_Q_tax_cons(a, b, c, d, t),eq_P(a, b, c, d, t)]], rgbcolor = consumer_color, alpha = .9, legend_label = 'tax revenues - consumers') tax_rev_producer_plot_tax_cons = polygon2d([[eq_Q_tax_cons(a, b, c, d, t), P_seller_cons(a, b, c, d, t)], [0, P_seller_cons(a, b, c, d, t)], [0, eq_P(a, b, c, d)], [eq_Q_tax_cons(a, b, c, d, t), eq_P(a, b, c, d)]], rgbcolor = producer_color, alpha = .9, legend_label = 'tax revenues - producers') deadweight_loss_consumer_plot_tax_cons = polygon2d([[eq_Q(a, b, c, d), eq_P(a, b, c, d)], [eq_Q_tax_cons(a, b, c, d, t), eq_P(a, b, c, d)], [eq_Q_tax_cons(a, b, c, d, t), demand_inv(a, b, eq_Q_tax_cons(a, b, c, d, t))], ], rgbcolor = consumer_color, alpha = .2, legend_label = 'deadweight loss - consumers') deadweight_loss_producer_plot_tax_cons = polygon2d([[eq_Q_tax_cons(a, b, c, d, t), P_seller_cons(a, b, c, d, t)], [eq_Q_tax_cons(a, b, c, d, t), eq_P(a, b, c, d)], [eq_Q(a, b, c, d), eq_P(a, b, c, d)]], rgbcolor = producer_color, alpha = .2, legend_label = 'deadweight loss - producers') demand_tax_plot = plot(demand_tax_inv(a, b, Q, t), (Q, 0, qmax(a, b)), linestyle = ('--'), rgbcolor = (consumer_color), legend_label = 'demand - proportional tax', ticks = [[eq_Q(a, b, c, d)] if t == 0 else [eq_Q(a, b, c, d), eq_Q_tax_cons(a, b, c, d, t)], [eq_P(a, b, c, d)] if t == 0 else [eq_P(a, b, c, d), P_seller_cons(a, b, c, d, t), demand_inv(a, b, eq_Q_tax_cons(a, b, c, d, t))]], tick_formatter=[["$Q^*_{no-tax}$"] if t == 0 else ["$Q^*_{no-tax}$", "$Q^*_{tax-cons.}$"], ["$P^*_{no-tax}$"] if t == 0 else ["$P^*_{no-tax}$", "$P^*_{seller, tax-cons.}$", "$P^*_{buyer, tax-cons.}$"]], axes_labels_size = 1, title = "Proportional tax - Consumer" ) supply_plot_tax_cons = plot(supply_inv(c, d, Q), (Q, 0, qmax(a, b)), linestyle = ('-'), rgbcolor = (producer_color), legend_label = 'supply', axes_labels=['quantity','price']) demand_plot_tax_cons = plot(demand_inv(a, b, Q), (Q, 0, qmax(a, b)), linestyle = ('-'), rgbcolor = (consumer_color), legend_label = 'demand') dot_tax_cons = point([(eq_Q_tax_cons(a, b, c, d, t), eq_P_tax_cons(a, b, c, d,t ))] if t > 0 else [], pointsize=60, rgbcolor=(.4, .4, .4)) dot = point((eq_Q(a, b, c, d), eq_P(a, b, c, d)), pointsize=60, rgbcolor=(0,0,0) if t == 0 else (.4, .4, .4)) P_tot_tax_prod = demand_plot_tax_prod + consumer_surplus_plot_tax_prod + tax_rev_consumer_plot_tax_prod + deadweight_loss_consumer_plot_tax_prod + supply_plot_tax_prod + supply_tax_plot_tax_prod + producer_surplus_plot_tax_prod + tax_rev_producer_plot_tax_prod + deadweight_loss_producer_plot_tax_prod + dot + dot_tax_prod P_tot_tax_prod.set_legend_options(handlelength=2, borderaxespad = 0, labelspacing =.05, bbox_to_anchor=(1.05, 1), loc=2) P_tot_tax_prod.fontsize(14) P_tot_tax_cons = demand_plot_tax_cons + demand_tax_plot + consumer_surplus_plot_tax_cons + tax_rev_consumer_plot_tax_cons + deadweight_loss_consumer_plot_tax_cons + supply_plot_tax_cons + producer_surplus_plot_tax_cons + tax_rev_producer_plot_tax_cons + deadweight_loss_producer_plot_tax_cons + dot + dot_tax_cons P_tot_tax_cons.set_legend_options(handlelength=2, borderaxespad = 0, labelspacing =.05, bbox_to_anchor=(1.05, 1), loc=2) P_tot_tax_cons.fontsize(14) show(P_tot_tax_prod, ymin = -verticalPad(a, b), ymax = pmax(a, b), xmin = -1, xmax = (a + a/10) if zoom == True else qmax(a, b) if qmax(a, b) < 20 else 20, figsize = 7) show(P_tot_tax_cons, ymin = -verticalPad(a), ymax = pmax(a), xmin = -1, xmax = (a + a/10) if zoom == True else qmax(a, b) if qmax(a, b) < 20 else 20, figsize = 7)

As it can be seen by the graphs, when in a competitive setting, introducing a tax tt on producers or consumers leads to equivalent outcomes, in particular:

  • A commodity tax formally paid by the producers leads to the same market equilibrium: the equilibrium quantity of good traded in the market is the same as well as the price paid by the buyer and the price received by the seller

  • The tax incidence on consumers and producers is the same regardless of who is formally entitled to pay the tax

  • The consumer and producer surplus, as well as revenues, are the same regardless of who is formally entitled to pay the tax