#!/usr/bin/env python3 """Figure ch43 — municipalité fictive de Rivière-Fictive (DONNÉES SYNTHÉTIQUES) : 625 lots, classes d'exposition le long de la rivière, lots riverains du lac (aménité sans exposition) ; (b) prix par m² habitable des ventes selon la distance à la rivière, avant et après l'inondation de 2019 (moyennes par bande de 40 m). Sortie : assets/figures/ch43/ch43-fig-carte-riverain.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, pandas as pd, matplotlib.pyplot as plt from matplotlib.patches import Rectangle from traite.style import setup, palette, savefig, LARGEUR import ch43_risques as cas def main(): setup() lots, ventes = cas.charger_ou_generer(ecrire=False) fig, (a, b) = plt.subplots(1, 2, figsize=(LARGEUR, 3.4), gridspec_kw={"width_ratios": [1.15, 1]}) 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"} for _, L in lots.iterrows(): 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)) if L["rive"] and L["classe"] == "hors zone": 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)) a.add_patch(Rectangle((0, -60), cas.NCOL * cas.PAS, 60, facecolor=palette.seq[2], edgecolor="none")) a.add_patch(Rectangle((cas.NCOL * cas.PAS, -60), 70, cas.NLIG * cas.PAS + 60, facecolor=palette.seq[2], edgecolor="none")) a.text(cas.NCOL * cas.PAS / 2, -32, "rivière", ha="center", va="center", fontsize=7.5, color="white") a.text(cas.NCOL * cas.PAS + 35, cas.NLIG * cas.PAS / 2, "lac", rotation=90, ha="center", va="center", fontsize=7.5, color="white") 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) a.set_xticks([]); a.set_yticks([]); a.set_title("(a) Lots et classes d'exposition", loc="left") for i, (c, col) in enumerate(couleurs.items()): a.add_patch(Rectangle((cas.NCOL * cas.PAS + 90 + 0, 0), 0, 0, facecolor=col)) 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])] a.legend(handles, list(couleurs) + ["vue sur l'eau hors zone (lac)"], loc="upper left", fontsize=6.8, ncol=2, frameon=True, framealpha=0.9, bbox_to_anchor=(0.0, 1.0)) # (b) prix/m² par bande de distance, avant / après, lots non riverains du lac seulement v = ventes[~ventes["id_lot"].str[-2:].astype(int).isin(cas.COLS_LAC)].copy() v["pm2"] = v["prix_vente"] / v["sup_habitable_m2"] t = (pd.to_datetime(v["date_vente"]) - pd.Timestamp(cas.DATE_REF)).dt.days / 365.25 v["pm2_t"] = v["pm2"] / (1 + cas.TAUX_MARCHE) ** t # ramené à la date de référence v["bande"] = (v["dist_riviere_m"] // 40).clip(upper=12) for post, col, lab in [(0, palette.cat[2], "avant mai 2019"), (1, palette.cat[0], "après mai 2019")]: g = v[v["post"] == post].groupby("bande")["pm2_t"].mean() b.plot(g.index * 40 + 20, g.values, marker="o", markersize=3.5, color=col, linewidth=1.3, label=lab) for xb, lab in [(80, "TE | E"), (160, "E | M"), (240, "M | F"), (280, "F | hors zone")]: b.axvline(xb if xb != 280 else 280, color=palette.ink2, linewidth=0.6, linestyle=":") b.set_xlabel("Distance à la rivière (m) — bandes de 40 m, lots du lac exclus"); b.set_ylabel("Prix par m² habitable, à la date de référence ($/m²)") b.set_title("(b) Prix unitaire et distance à la rivière", loc="left"); b.legend(loc="lower right", fontsize=7) fig.tight_layout() savefig(fig, "ch43/ch43-fig-carte-riverain.pdf") if __name__ == "__main__": main()