Key graphs

Chapter 3 — the diagrams to master, and how to read them

Five pictures carry the whole chapter. Each is drawn from the guide’s model (_model.py): the chapter’s equations with Cobb–Douglas technology \(f(k) = A k^{1-\alpha}\), where \(\alpha\) is the labour share (book eq. 3.19), and no depreciation. The chapter gives no calibration, so all parameters are illustrative: \(A = 1\), \(\alpha = 2/3\), \(\rho = 0.04\), \(n = 0.01\), \(\sigma = 1\). The shapes and directions are what you must master; the numbers only make them concrete.

Consumption grows wherever the return on capital beats impatience

Code
def draw(ax, c):
    k = np.linspace(4, 70, 400)
    mpk = m.f_prime(k)
    ax.plot(k, mpk, color=c["blue"], label=r"marginal product $f'(k)$")
    ax.axhline(m.RHO, color=c["orange"], ls="--", label=r"impatience $\rho$")
    ax.fill_between(k, mpk, m.RHO, where=k <= ks, color=c["green"], alpha=0.18)
    ax.fill_between(k, mpk, m.RHO, where=k >= ks, color=c["red"], alpha=0.15)
    ax.axvline(ks, color=c["muted"], lw=1, ls=":")
    ax.annotate(r"$\dot c / c > 0$", (ks * 0.45, m.RHO * 1.35), color=c["green"], fontsize=13)
    ax.annotate(r"$\dot c / c < 0$", (ks * 1.6, m.RHO * 0.72), color=c["red"], fontsize=13)
    ax.annotate(r"$k^*$", (ks, m.RHO * 0.45), color=c["fg"], ha="center")
    ax.set_xlabel(r"capital per capita $k$")
    ax.set_ylabel("rate per year")
    ax.set_ylim(0, 0.1)
    ax.legend(loc="upper right")
keygraph(draw, "euler")
Figure 1: The Euler equation in one picture: consumption grows (ċ/c > 0) to the left of k*, where the marginal product of capital exceeds the rate of time preference ρ, and falls to its right. Illustrative parameters.

How to read it. The blue curve is the return on saving one more unit as capital. It falls with \(k\) because of diminishing returns. The dashed line is how much less you value consumption tomorrow. Where the curve is above the line (green), postponing consumption pays, so consumption grows. Where it is below (red), consumption shrinks. They cross at \(k^*\), where \(f'(k^*) = \rho\).

What shifts it. A fall in \(\rho\) lowers the dashed line, so the crossing moves right and the steady-state capital stock rises. Higher productivity \(A\) lifts the blue curve, with the same effect. A larger \(\sigma\) does not move the crossing; it only makes consumption respond more strongly to the gap.

Practise: Exercise 1 · Quiz 2

Optimal saving stops short of the golden rule

Code
def draw(ax, c):
    k = np.linspace(0.5, 420, 600)
    ax.plot(k, m.c_kdot0(k), color=c["blue"], label=r"$\dot k = 0$:  $c = f(k) - nk$")
    ax.axvline(ks, color=c["orange"], ls="--", label=r"modified golden rule $f'(k^*) = \rho$")
    ax.axvline(kg, color=c["purple"], ls=":", label=r"golden rule $f'(k_G) = n$")
    ax.plot([ks], [cs], "o", color=c["orange"], ms=8)
    ax.plot([kg], [m.c_kdot0(kg)], "o", color=c["purple"], ms=8)
    ax.annotate("E", (ks, cs), xytext=(8, -16), textcoords="offset points", color=c["fg"])
    ax.annotate("G", (kg, m.c_kdot0(kg)), xytext=(6, 6), textcoords="offset points", color=c["fg"])
    ax.set_xlabel(r"capital per capita $k$")
    ax.set_ylabel(r"consumption per capita $c$")
    ax.set_ylim(0, m.c_kdot0(kg) * 1.25)
    ax.legend(loc="lower right", fontsize=10)
keygraph(draw, "golden")
Figure 2: The k̇ = 0 locus c = f(k) − nk peaks at the golden rule k_G, where f′(k_G) = n. The optimal steady state E sits to its left, at the modified golden rule f′(k*) = ρ, because ρ > n. Illustrative parameters.

How to read it. Every point on the hump is a possible steady state. There consumption is exactly what keeps capital per person constant. Point G maximises steady-state consumption (the Solow golden rule). The optimum E has less capital: with illustrative parameters \(k^* \approx\) 24 versus \(k_G \approx\) 192.

What shifts it. E’s position is set by \(\rho\) alone (given technology). G’s is set by \(n\) alone. Since \(\rho > n\), E is always left of G: discounting makes it optimal to consume more on the way rather than build the consumption-maximising capital stock. A fall in \(\rho\) moves E towards G. Faster population growth \(n\) moves G left and lowers the hump.

Practise: Worked example · Exercise 2 · Quiz 4

Only the saddle path reaches the steady state

Code
kp, cp = m.saddle_path(2, 75)

def diverge(k0, c0, T=400):
    stop_lo = lambda t, y: y[0] - 0.5; stop_lo.terminal = True
    stop_c = lambda t, y: y[1] - 0.05; stop_c.terminal = True
    stop_hi = lambda t, y: y[0] - 75; stop_hi.terminal = True
    sol = solve_ivp(m.dynamics, (0, T), [k0, c0], events=[stop_lo, stop_c, stop_hi], max_step=0.5)
    return sol.y

def draw(ax, c):
    k = np.linspace(0.5, 75, 400)
    ax.plot(k, m.c_kdot0(k), color=c["blue"], label=r"$\dot k = 0$")
    ax.axvline(ks, color=c["orange"], label=r"$\dot c = 0$")
    ax.plot(kp, cp, color=c["green"], lw=3.2, label="saddle path")
    k0 = 6.0
    c_sp = float(np.interp(k0, kp, cp))
    for dc, col in ((0.08, c["red"]), (-0.08, c["purple"])):
        y = diverge(k0, c_sp + dc)
        ax.plot(y[0], y[1], color=col, lw=1.4, ls="--")
    # direction arrows in the four regions (signs of kdot, cdot from eqs. 3.5 and 3.15)
    for (kx, cy) in ((10, 1.2), (10, 3.1), (45, 2.4), (45, 4.2)):
        dk, dcdt = m.dynamics(0, [kx, cy])
        ax.annotate("", xy=(kx + 5 * np.sign(dk), cy), xytext=(kx, cy),
                    arrowprops=dict(arrowstyle="->", color=c["fg"], lw=1.4))
        ax.annotate("", xy=(kx, cy + 0.35 * np.sign(dcdt)), xytext=(kx, cy),
                    arrowprops=dict(arrowstyle="->", color=c["fg"], lw=1.4))
    ax.plot([ks], [cs], "o", color=c["fg"], ms=7)
    ax.annotate("E", (ks, cs), xytext=(8, -14), textcoords="offset points", color=c["fg"])
    ax.set_xlim(0, 75); ax.set_ylim(0, 5)
    ax.set_xlabel(r"capital per capita $k$")
    ax.set_ylabel(r"consumption per capita $c$")
    ax.legend(loc="upper left", fontsize=10)
keygraph(draw, "phase")
Figure 3: Phase diagram of the Ramsey model. Arrows show the direction of motion in each region; the saddle path (thick) is the only trajectory into the steady state E. Paths starting off it diverge — towards zero capital or towards over-accumulation — and violate the transversality condition. Illustrative parameters.

How to read it. The two loci split the plane into four regions. Above the \(\dot k = 0\) hump people consume more than output net of capital widening, so capital falls (horizontal arrows point left). Left of \(\dot c = 0\), \(f'(k) > \rho\), so consumption rises (vertical arrows point up). Only along the green saddle path do the two motions lead into E. Capital is predetermined, so given \(k_0\) the economy reaches the saddle path by a jump in consumption.

What shifts it. A change in \(\rho\) moves the \(\dot c = 0\) line and with it the whole saddle path. Changes in \(n\) or technology move the hump. The dashed paths show what happens if consumption starts too high (capital runs out) or too low (capital over-accumulates past the golden rule). The transversality condition rules both out. Near E the saddle path’s slope is 0.071 and the economy closes half of any gap to E in about 17 years (illustrative).

Practise: Exercise 6 · Quiz 6 · 🔴 Proof of saddle-path stability

A permanent fall in ρ: consumption dips, then climbs to a higher steady state

Code
def draw(ax, c):
    k = np.linspace(0.5, 75, 400)
    ax.plot(k, m.c_kdot0(k), color=c["blue"], label=r"$\dot k = 0$ (unchanged)")
    ax.axvline(ks, color=c["muted"], ls=":", label=r"old $\dot c = 0$")
    ax.axvline(ks_new, color=c["orange"], label=r"new $\dot c = 0$")
    ax.plot(kp_new, cp_new, color=c["green"], lw=3, label="new saddle path")
    seg = (kp_new >= ks) & (kp_new <= ks_new)
    ax.annotate("", xy=(ks, c_impact), xytext=(ks, cs),
                arrowprops=dict(arrowstyle="->", color=c["red"], lw=2))
    for pt, lab, off in (((ks, cs), "E", (-16, 6)), ((ks, c_impact), "A", (-16, -14)),
                         ((ks_new, cs_new), "E′", (8, -14))):
        ax.plot([pt[0]], [pt[1]], "o", color=c["fg"], ms=7)
        ax.annotate(lab, pt, xytext=off, textcoords="offset points", color=c["fg"])
    ax.plot(kp_new[seg], cp_new[seg], color=c["red"], lw=1.6, ls="--")
    ax.set_xlim(0, 75); ax.set_ylim(0, 5)
    ax.set_xlabel(r"capital per capita $k$")
    ax.set_ylabel(r"consumption per capita $c$")
    ax.legend(loc="upper left", fontsize=10)
keygraph(draw, "shock")
Figure 4: An unexpected, permanent fall in the rate of time preference (ρ from 0.04 to 0.03, illustrative). The ċ = 0 line moves right; consumption jumps down from E to A on the new saddle path, then consumption and capital rise together to E′.

How to read it. Households suddenly become more patient. The \(\dot k = 0\) hump does not move (\(\rho\) does not enter it). The \(\dot c = 0\) line moves right, to the new modified golden rule. Capital cannot jump, so consumption does: down from E to A, onto the new saddle path. In this illustration that is a fall of about 15%. The extra saving builds capital, and the economy climbs to E′, where consumption is about 12% higher than at E.

What shifts it. A permanent rise in \(\rho\) is the mirror image: consumption jumps up, then capital and consumption decline. For an anticipated or transitory change, consumption jumps only when the news arrives. It then moves so that the economy lands exactly on the relevant saddle path when the change takes effect or ends; an anticipated jump would offer infinite capital gains.

Practise: Exercise 4 · Quiz 3

On impact only consumption moves; capital follows gradually

Code
t, kt, ct = m.transition(ks, T=150, rho=RHO_NEW)

def draw(ax, c):
    pre = np.linspace(-20, 0, 20)
    ax.plot(np.r_[pre, t], np.r_[np.full(20, 100.0), 100 * kt / ks], color=c["blue"], label=r"capital $k_t$")
    ax.plot(np.r_[pre, t], np.r_[np.full(20, 100.0), 100 * ct / cs], color=c["orange"], label=r"consumption $c_t$")
    ax.axvline(0, color=c["muted"], ls=":")
    ax.annotate(r"shock: $\rho$ falls", (1.5, 102), color=c["muted"], fontsize=11)
    ax.set_xlabel("years after the shock")
    ax.set_ylabel("index, old steady state = 100")
    ax.legend(loc="lower right")
keygraph(draw, "paths")
Figure 5: Time paths after the permanent fall in ρ at t = 0 (illustrative), relative to the old steady state (= 100). Consumption jumps down on impact, then both variables rise smoothly to their new, higher steady-state levels.

How to read it. This is the same experiment as above, plotted against time. Capital (blue) is a stock: it cannot jump, and rises gradually as households save more. Consumption (orange) is a choice: it jumps down on impact, then overtakes its old level and keeps rising.

What shifts it. A higher elasticity of intertemporal substitution \(\sigma\) makes households more willing to shift consumption over time, so the impact jump and the adjustment are faster. The long-run levels depend only on \(\rho\), \(n\) and technology.

Practise: Exercise 4 · Quiz 5

Explore it yourself

Move the sliders and watch the phase diagram respond. The interactive model uses the same equations as the graphs above, checked automatically against the Python model. Keep \(\rho > n\): the problem is not well defined otherwise (chapter footnote 5).

Try these:

  • Raise ρ. Where do \(k^*\) and \(c^*\) go, and does the golden rule move?
  • Raise n. Which curve moves?
  • Change σ. Does the steady state move? What happens to the speed of convergence?
Back to top