#!/usr/bin/env python3 """Figure ch24 — courbes de dépréciation du bâtiment en fonction de l'âge (DONNÉES SYNTHÉTIQUES, cas 1, graine 20261031) : (a) taux extraits du marché pour les 600 ventes, médianes par tranche d'âge et ajustement quadratique ; (b) profils comparés : âge-vie linéaire (60 ans), extraction, courbe hédonique et profil « vrai » du générateur convertis en dépréciation du bâtiment (part du terrain α), avec les deux lectures du sujet à 28 ans. Sortie : assets/figures/ch24/ch24-fig-courbes.pdf""" import sys, pathlib ROOT = pathlib.Path(__file__).resolve().parents[3] sys.path.insert(0, str(ROOT / "analysis/python")); sys.path.insert(0, str(ROOT / "analysis/python/cases")) import numpy as np, matplotlib.pyplot as plt from traite.style import setup, palette, savefig, LARGEUR import ch24_depreciation as cas def main(): setup() d = cas.charger() w, vl = cas.extraction(d["ventes"], d["modele"], d["cn"]["total"]) aj = cas.ajuster_profil(w); q = aj["quadratique"] vlr = cas.valeur_terrain_retenue(vl) pr = cas.profils(d["modele"], d["sujet"], vlr["retenue"], q) var = cas.variantes_physique(d["cn"], d["fiche"], d["travaux"]) fig, (a, b) = plt.subplots(1, 2, figsize=(LARGEUR, 3.1), gridspec_kw={"wspace": 0.28}) # (a) nuage + médianes par tranche + ajustement quadratique a.scatter(w["age"], w["taux"] * 100, s=7, color=palette.cat[0], alpha=0.25, linewidths=0, label="Ventes (600)") tr = cas.tranches(w) mids = [5, 15, 25, 35, 45, 55, 75] a.plot(mids, tr["median"].values * 100, "o", color=palette.cat[1], ms=5, label="Médiane par tranche de 10 ans") ages = np.arange(0, 100) a.plot(ages, cas.taux_quadratique(q, ages) * 100, color=palette.cat[1], lw=1.8, label="Ajustement quadratique") a.plot(ages, np.minimum(ages / 60, 1) * 100, color=palette.ink2, lw=1.2, ls="--", label="Âge-vie linéaire (60 ans)") a.set_xlim(0, 100); a.set_ylim(-30, 100) a.set_xlabel("Âge chronologique (ans)"); a.set_ylabel("Dépréciation extraite (% du coût neuf)") a.set_title("(a) Extraction de marché, 600 ventes", loc="left", fontsize=9) a.legend(loc="upper left", fontsize=7) # (b) profils comparés ag = pr["ages"] b.plot(ag, pr["age_vie"] * 100, color=palette.ink2, lw=1.2, ls="--", label="Âge-vie linéaire (60 ans)") b.plot(ag, pr["extraction"] * 100, color=palette.cat[1], lw=1.8, label="Extraction de marché (quadratique)") b.plot(ag, pr["hedonique_bat"] * 100, color=palette.cat[0], lw=1.8, label="Hédonique, converti au bâtiment") b.plot(ag, pr["generateur_bat"] * 100, color=palette.cat[2], lw=1.6, ls=":", label="Profil du générateur, converti") b.legend(loc="upper left", fontsize=7) # sujet à 28 ans b.plot([28], [var["ventilee"]["taux"] * 100], "D", color=palette.cat[5], ms=6) b.annotate(f"Sujet, ventilée : {var['ventilee']['taux']*100:.1f} %", (28, var["ventilee"]["taux"] * 100), xytext=(40, 58), fontsize=7.5, color=palette.ink, arrowprops=dict(arrowstyle="-", color=palette.ink2, lw=0.6)) t28 = float(cas.taux_quadratique(q, 28)) b.plot([28], [t28 * 100], "o", color=palette.cat[1], ms=6) b.annotate(f"Sujet, extraction : {t28*100:.1f} %", (28, t28 * 100), xytext=(36, 6), fontsize=7.5, color=palette.ink, arrowprops=dict(arrowstyle="-", color=palette.ink2, lw=0.6)) b.set_xlim(0, 82); b.set_ylim(0, 100) b.set_xlabel("Âge (ans)"); b.set_ylabel("Dépréciation du bâtiment (% du coût neuf)") b.set_title(f"(b) Profils comparés (part du terrain α = {pr['alpha']:.2f})", loc="left", fontsize=9) out = savefig(fig, "ch24/ch24-fig-courbes.pdf"); print("OK", out) if __name__ == "__main__": main()