SPB Git
4.3 KB · 59 lines python
1#!/usr/bin/env python32"""Figure ch43 — municipalité fictive de Rivière-Fictive (DONNÉES SYNTHÉTIQUES) : 625 lots, classes d'exposition le long de la3rivière, lots riverains du lac (aménité sans exposition) ; (b) prix par m² habitable des ventes selon la distance à la rivière,4avant et après l'inondation de 2019 (moyennes par bande de 40 m).5Sortie : assets/figures/ch43/ch43-fig-carte-riverain.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, pandas as pd, matplotlib.pyplot as plt10from matplotlib.patches import Rectangle11from traite.style import setup, palette, savefig, LARGEUR12import ch43_risques as cas131415def main():16    setup()17    lots, ventes = cas.charger_ou_generer(ecrire=False)18    fig, (a, b) = plt.subplots(1, 2, figsize=(LARGEUR, 3.4), gridspec_kw={"width_ratios": [1, 1.15]})19    couleurs = {"très élevée": palette.seq[-1], "élevée": palette.seq[-2], "modérée": palette.seq[-3], "faible": palette.seq[-4], "hors zone": "#e9e7e2"}20    for _, L in lots.iterrows():21        a.add_patch(Rectangle((L["x"] * cas.PAS, L["y"] * cas.PAS), cas.PAS, cas.PAS, facecolor=couleurs[L["classe"]], edgecolor="white", linewidth=0.3))22        if L["rive"] and L["classe"] == "hors zone":23            a.add_patch(Rectangle((L["x"] * cas.PAS + 6, L["y"] * cas.PAS + 6), cas.PAS - 12, cas.PAS - 12, facecolor="none", edgecolor=palette.cat[1], linewidth=0.7))24    a.add_patch(Rectangle((0, -60), cas.NCOL * cas.PAS, 60, facecolor=palette.seq[2], edgecolor="none"))25    a.add_patch(Rectangle((cas.NCOL * cas.PAS, -60), 70, cas.NLIG * cas.PAS + 60, facecolor=palette.seq[2], edgecolor="none"))26    a.text(cas.NCOL * cas.PAS / 2, -32, "rivière", ha="center", va="center", fontsize=7.5, color="white")27    a.text(cas.NCOL * cas.PAS + 35, cas.NLIG * cas.PAS / 2, "lac", rotation=90, ha="center", va="center", fontsize=7.5, color="white")28    a.set_xlim(-10, cas.NCOL * cas.PAS + 80); a.set_ylim(-70, cas.NLIG * cas.PAS + 10); a.set_aspect("equal"); a.grid(False)29    a.set_xticks([]); a.set_yticks([]); a.set_title("(a) Lots et classes d'exposition", loc="left")30    for i, (c, col) in enumerate(couleurs.items()):31        a.add_patch(Rectangle((cas.NCOL * cas.PAS + 90 + 0, 0), 0, 0, facecolor=col))32    handles = [Rectangle((0, 0), 1, 1, facecolor=couleurs[c], edgecolor="white") for c in couleurs] + [Rectangle((0, 0), 1, 1, facecolor="none", edgecolor=palette.cat[1])]33    a.legend(handles, list(couleurs) + ["vue sur l'eau hors zone (lac)"], loc="upper center", fontsize=6.8, ncol=3, bbox_to_anchor=(0.5, -0.02))34    # (b) ln P ajusté des attributs physiques et du temps (coefficients estimés hors zone), moyenne par classe avant / après, IC à 95 %35    import ch43_risques as c236    v = ventes.copy(); y = np.log(v["prix_vente"].values)37    te = v[(v["expose"] == 0) & (v["rive"] == 0)]38    r = c2.h.mco(c2._X(te, []), np.log(te["prix_vente"].values)); b0 = r["beta"]39    X = c2._X(v, []); v["ln_aj"] = y - X[:, 1:] @ b0[1:]           # ln P net des attributs et de la tendance (constante conservée)40    ref = v.loc[(v["expose"] == 0) & (v["rive"] == 0), "ln_aj"].mean()41    v["ecart"] = (v["ln_aj"] - ref) * 10042    ordre = ["très élevée", "élevée", "modérée", "faible", "hors zone"]43    x = np.arange(len(ordre)); w = 0.3644    for post, col, lab, dx in [(0, palette.cat[2], "avant mai 2019", -w / 2), (1, palette.cat[0], "après mai 2019", w / 2)]:45        g = v[(v["post"] == post) & (v["rive"] == 0) | ((v["post"] == post) & (v["classe"].isin(["très élevée", "élevée"])))]46        g = g.groupby("classe")["ecart"].agg(["mean", "std", "count"]).reindex(ordre)47        b.bar(x + dx, g["mean"], w, color=col, label=lab)48        b.errorbar(x + dx, g["mean"], yerr=1.96 * g["std"] / np.sqrt(g["count"]), fmt="none", ecolor=palette.ink2, elinewidth=0.9, capsize=2)49    b.axhline(0, color=palette.ink2, linewidth=0.8)50    b.set_xticks(x); b.set_xticklabels(["très\nélevée", "élevée", "\nmodérée", "faible", "\nhors zone"], fontsize=7)51    b.set_ylabel("ln P net des attributs, écart aux lots hors zone (pts de %)")52    b.set_title("(b) Écart de prix par classe, avant / après", loc="left"); b.legend(loc="lower right", fontsize=7)53    fig.tight_layout()54    savefig(fig, "ch43/ch43-fig-carte-riverain.pdf")555657if __name__ == "__main__":58    main()59
Files · cd76781f94cbc7113926bd8a4bd920d14c17c982
Menu

Theme