SPB Git
5.7 KB · 92 lines python
1#!/usr/bin/env python32"""Figure ch03 — Modèle des quatre quadrants (DiPasquale–Wheaton) tracé à partir des paramètres pédagogiques du marché type3(analysis/python/cases/ch03_cycles.py, SYNTHÉTIQUE). Équilibre de référence (trait plein) et nouvel équilibre après une baisse4du taux de capitalisation de 5 % à 4 % (tirets), avec la réaction de court terme (stock fixe) en pointillé.5Sortie : assets/figures/ch03/ch03-fig-quatre-quadrants.pdf"""6import sys, pathlib7ROOT = pathlib.Path(__file__).resolve().parents[3]8sys.path.insert(0, str(ROOT / "analysis/python")); sys.path.insert(0, str(ROOT / "analysis/python/cases"))9import numpy as np, matplotlib.pyplot as plt10from traite.style import setup, palette, savefig, LARGEUR11import ch03_cycles as cas121314def main():15    setup()16    p = cas.Parametres4Q()17    base = cas.equilibre_4q(p)18    i2 = 0.0419    nouv = cas.equilibre_4q(p, i=i2)20    ct = cas.court_terme_4q(p, i=i2)21    k = 1000.0  # affichage en milliers22    c0, c1 = palette.cat[0], palette.cat[1]23    fig, ax = plt.subplots(figsize=(LARGEUR, LARGEUR * 0.92))24    # bornes25    Smax, Pmax, Rmax, Cmax = 150, 420, 25, 3.226    ax.set_xlim(-Pmax, Smax); ax.set_ylim(-Cmax, Rmax)27    ax.axhline(0, color=palette.ink, lw=0.9); ax.axvline(0, color=palette.ink, lw=0.9)28    ax.grid(False)29    for s in ("left", "bottom"):30        ax.spines[s].set_visible(False)31    ax.set_xticks([]); ax.set_yticks([])32    # --- NE : marché de l'espace, D(R) = S  → R = (a − S)/b33    S = np.linspace(60, 150, 50) * k34    ax.plot(S / k, (p.a - S) / p.b / k, color=c0, lw=1.8)35    ax.plot(S / k, (1.0 * p.a - S) / p.b / k, color=c0, lw=0, label="_")36    # --- NW : marché des actifs, P = R / i  (P à gauche, R en haut)37    R = np.linspace(0, Rmax, 50) * k38    ax.plot(-R / p.i / k, R / k, color=c0, lw=1.8)39    ax.plot(-R / i2 / k, R / k, color=c1, lw=1.8, ls="--")40    # --- SW : construction, C = (P − c0)/c1 (P à gauche, C en bas)41    P = np.linspace(p.c0, Pmax * k, 50)42    ax.plot(-P / k, -(P - p.c0) / p.c1 / k, color=c0, lw=1.8)43    # --- SE : ajustement du stock, S = C/δ  (C en bas, S à droite)44    C = np.linspace(0, Cmax, 50) * k45    ax.plot(C / p.delta / k, -C / k, color=c0, lw=1.8)4647    def rectangle(eq, color, ls, lw=1.0):48        Sx, Rx, Px, Cx = eq["S"] / k, eq["R"] / k, eq["P"] / k, eq["C"] / k49        ax.plot([Sx, Sx], [0, Rx], color=color, lw=lw, ls=ls)50        ax.plot([-Px, Sx], [Rx, Rx], color=color, lw=lw, ls=ls)51        ax.plot([-Px, -Px], [Rx, -Cx], color=color, lw=lw, ls=ls)52        ax.plot([-Px, Sx], [-Cx, -Cx], color=color, lw=lw, ls=ls)53        ax.plot([Sx, Sx], [-Cx, 0], color=color, lw=lw, ls=ls)5455    rectangle(base, c0, "-")56    rectangle(nouv, c1, "--")57    # court terme : stock fixe, prix bondit à R0/i258    ax.plot([-ct["P"] / k, base["S"] / k], [base["R"] / k, base["R"] / k], color=c1, lw=1.0, ls=":")59    ax.plot([-ct["P"] / k, -ct["P"] / k], [base["R"] / k, -ct["C"] / k], color=c1, lw=1.0, ls=":")60    ax.plot([-ct["P"] / k, base["S"] / k], [-ct["C"] / k, -ct["C"] / k], color=c1, lw=1.0, ls=":")61    # points62    ax.plot(base["S"] / k, base["R"] / k, "o", color=c0, ms=4); ax.plot(nouv["S"] / k, nouv["R"] / k, "o", color=c1, ms=4)63    ax.plot(-base["P"] / k, base["R"] / k, "o", color=c0, ms=4); ax.plot(-nouv["P"] / k, nouv["R"] / k, "o", color=c1, ms=4)64    ax.plot(-ct["P"] / k, base["R"] / k, "o", color=c1, ms=4, mfc="white")65    # étiquettes d'axes et de quadrants66    ax.text(Smax, 0.6, "Stock $S$ (milliers de log.)", ha="right", va="bottom", fontsize=8)67    ax.text(-Pmax, 0.6, "Prix $P$ (k\\$/log.)", ha="left", va="bottom", fontsize=8)68    ax.text(1.5, Rmax, "Loyer $R$ (k\\$/log./an)", ha="left", va="top", fontsize=8)69    ax.text(1.5, -Cmax, "Construction $C$ (milliers de log./an)", ha="left", va="bottom", fontsize=8)70    ax.text(Smax * 0.98, Rmax * 0.93, "Marché de l'espace\n$D(R) = S$", ha="right", va="top", fontsize=8, color=palette.ink2)71    ax.text(-Pmax * 0.98, Rmax * 0.93, "Marché des actifs\n$P = R/i$", ha="left", va="top", fontsize=8, color=palette.ink2)72    ax.text(-Pmax * 0.98, -Cmax * 0.93, "Construction\n$C = (P - c_0)/c_1$", ha="left", va="bottom", fontsize=8, color=palette.ink2)73    ax.text(Smax * 0.98, -Cmax * 0.93, "Ajustement du stock\n$\\Delta S = C - \\delta S = 0$", ha="right", va="bottom", fontsize=8, color=palette.ink2)74    # annotations numériques75    ax.annotate(f"$S^*$ = {base['S']/k:.0f}", xy=(base["S"] / k, 0), xytext=(base["S"] / k + 2, 1.2), fontsize=7.5, color=c0)76    ax.annotate(f"{nouv['S']/k:.1f}", xy=(nouv["S"] / k, 0), xytext=(nouv["S"] / k + 2, 3.4), fontsize=7.5, color=c1)77    ax.annotate(f"$R^*$ = {base['R']/k:.1f}", xy=(0, base["R"] / k), xytext=(3, base["R"] / k + 0.6), fontsize=7.5, color=c0)78    ax.annotate(f"{nouv['R']/k:.1f}", xy=(0, nouv["R"] / k), xytext=(3, nouv["R"] / k - 1.9), fontsize=7.5, color=c1)79    ax.annotate(f"$P^*$ = {base['P']/k:.0f}", xy=(-base["P"] / k, 0), xytext=(-base["P"] / k - 6, 1.2), fontsize=7.5, color=c0, ha="right")80    ax.annotate(f"court terme : {ct['P']/k:.0f}", xy=(-ct["P"] / k, 0), xytext=(-ct["P"] / k - 4, -0.9), fontsize=7.5, color=c1, ha="right", va="top")81    ax.annotate(f"$C^*$ = {base['C']/k:.1f}", xy=(0, -base["C"] / k), xytext=(3, -base["C"] / k - 0.1), fontsize=7.5, color=c0, va="top")82    from matplotlib.lines import Line2D83    h = [Line2D([], [], color=c0, lw=1.8, label="équilibre de référence ($i$ = 5 %)"),84         Line2D([], [], color=c1, lw=1.8, ls="--", label="nouvel équilibre de long terme ($i$ = 4 %)"),85         Line2D([], [], color=c1, lw=1.0, ls=":", label="court terme (stock fixe)")]86    ax.legend(handles=h, loc="lower center", bbox_to_anchor=(0.5, -0.06), ncol=3, fontsize=7.5, frameon=False)87    out = savefig(fig, "ch03/ch03-fig-quatre-quadrants.pdf"); print("OK", out)888990if __name__ == "__main__":91    main()92
Files · 8dfc6ca7769188d087f58c82e02a063bfba99ae6
Menu

Theme