Matplotlibで経済学のグラフを描くとりくみ
ぼちぼち勉強を進めている。 目標はマニュアルや検索なしで経済学のグラフならささっと描けるようになることだ。
今はフリーハンドの方が楽だけれど、PowerPointよりは早くなってきた。
しばらく続けて、ブログの定番ネタにしようと思っていたけれど、意外と簡単だった。
無差別曲線と予算線
今日は無差別曲線と予算線を描く。 たぶんグラフの描画だから、書くではなく描くなんだけど、つい間違える。 間違いを見つけたら、指摘してもらえるとありがたい。
さて、無差別曲線だ。 あれはどうやって描いているのだろうか?
PowerPointでは、ベジェ曲線を使うけれど、意外ときれいに描くのは難しい。
少し前のテキストだと、ぎざぎざで直線をつなげました!がんばってます!的なものもあったけど、今はあまり見ない。 その変わり、少しだけいびつな曲線というのはよくみる。 授業やる教員のPowerPointでそうなってるのも多そうだ。
さて、一番シンプルな無差別曲線と予算制約はこれだ。 そして、この二本の曲線が接するようになっている。
U=x_1x_2 Y = p_1x_1+p_2x_2
授業でみた曲線はちゃんと接してただろうか? これも意外と難しい。
今日はこれに挑戦する。
なんも考えずに書くとこうなる。
<img src="" alt="" width="100%"/>
この図は、両者が接するように、ちょっとずつ動かしながら手作業で接するように描いている。 PowerPointでやるのと手間は大して変わらない。 ただ、無差別曲線はきれいだ。
もうちょっと凝りたい
一度描くだけなら、これでよいのだが、もう少し予算線が傾いているほうがいった要望もある。 そのたびに、手作業はめんどうだ!
そう考えて、一般解を得ることにした。初期値として、u,px, pyを与えれば、ある無差別曲線とそれに接する予算線を引いてくれる。 ついでに、x軸とy軸もグラフがうまく表示できる範囲に調整してくれる。
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
matplotlib.use('Agg')
useed = 9
px = 16
py = 4
u = py/px*useed**2
m = 2*px*(py/px*u)**0.5
x1 = np.linspace(0.1,m/px*1.2,500)
y1 = u/x1
y2 = m/py-px/py*x1
px3 = 4
m3 = 2*px3*(py/px3*u)**0.5
y3 = m3/py-px3/py*x1
myfig = plt.figure()
ax = myfig.add_subplot(111, xlabel='X1', ylabel='X2', xlim=(0,m/px*1.2),ylim=(0,m/py*1.2))
ax.set_xticks(ticks=[0])
ax.set_yticks(ticks=[])
ax.grid(color='gray')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.plot(x1, y1)
ax.plot(x1, y2,color='orange')
ax.plot(x1,y3, color='red')
myfig.savefig('images/myfig0513.png')
plt.close(myfig)
return 'images/myfig0513.png'
<img src="" alt="" width="100%"/> 試みに、x財の価格が4分の1になったケースを描いてみた。 赤の線がそれだ。 いずれの予算線も無差別曲線にきれいに接している。
ここでのポイントは、上記の一般式を解いて、予算(m)と予算線を自動で計算するようにしたことだ。 そのために与えるのは、効用Uではなく、効用Uを計算するための、useedという変数だ。 useedに整数を与えることで、Uやmが整数になりやすくなる。 特にオレンジの線の係数は整数になっている。
もう一つのポイントは、図中に線が大きく表示されるように、x軸とy軸の幅を調整していることだ。
大した工夫ではないけれど、ここは簡単なので意外と手作業で微調整したくなる部分だ。 けれども、その手間は毎回になるとけっこう大きなものになるので、計算でやってしまおう。
以上で、無差別曲線と予算線をMatplotlibで描くことができた。
次は、この図の交点に記号をつけていく。
つい最近、交点にラベルをつける方法は描いたが、接するばあいは対応できていないことに気付いた。 そこで先日のものを大幅に書き直して、こういうケースにも対応できるようにしている。