#!/usr/bin/env python3 """Figure ch43 — décote d'une zone inondable mesurée par quatre méthodes sur les ventes de Rivière-Fictive (DONNÉES SYNTHÉTIQUES). (a) estimation (ln P) et IC à 95 % par méthode, avec la vérité du générateur pour la cible de chaque méthode ; (b) décote par classe d'exposition avant l'inondation et stigmate (classe × après), estimées vs déclarées. Sortie : assets/figures/ch43/ch43-fig-effets-methodes.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 ch43_risques as cas def main(): setup() lots, ventes = cas.charger_ou_generer(ecrire=False) paires = cas.apparier(ventes); t = cas.effets_par_methode(ventes, paires); he = cas.hedoniques(ventes) fig, (a, b) = plt.subplots(1, 2, figsize=(LARGEUR, 3.6), gridspec_kw={"width_ratios": [1.35, 1]}) # (a) méthodes etiq = ["Paires\n(après 2019)", "Hédonique\nexposé", "Hédonique\nexposé + vue", "DiD rég. :\nexposé (avant)", "DiD rég. :\nexposé × après", "DiD rég. :\nsomme (après)", "DiD 2 × 2\n(stigmate)"] y = np.arange(len(t))[::-1] for i, (_, r) in enumerate(t.iterrows()): c = palette.cat[0] if np.isfinite(r["se"]) else palette.cat[2] if np.isfinite(r["se"]): a.plot([r["ic_bas"] * 100, r["ic_haut"] * 100], [y[i], y[i]], color=c, linewidth=1.4) a.plot(r["coef"] * 100, y[i], "o", color=c, markersize=5.5, zorder=3) a.plot(r["verite"] * 100, y[i], marker="|", color=palette.ink, markersize=11, markeredgewidth=1.6, linestyle="none", zorder=4) a.set_yticks(y); a.set_yticklabels(etiq, fontsize=7.5); a.axvline(0, color=palette.ink2, linewidth=0.8) a.set_xlabel("Effet sur ln P (points de pourcentage)"); a.set_title("(a) Sept estimations, quatre méthodes", loc="left") a.plot([], [], "o", color=palette.cat[0], label="estimation et IC à 95 %"); a.plot([], [], "o", color=palette.cat[2], label="estimation sans erreur-type") a.plot([], [], marker="|", color=palette.ink, linestyle="none", markersize=10, markeredgewidth=1.6, label="vérité du générateur (cible)") a.legend(loc="lower left", fontsize=7) # (b) classes cl = ["très élevée", "élevée", "modérée", "faible"]; cc = he["c_classes"] x = np.arange(len(cl)); w = 0.36 av = cc.loc[cl]; ap = cc.loc[[f"{c} × après" for c in cl]] b.bar(x - w / 2, av["coef"] * 100, w, color=palette.cat[0], label="avant 2019 (estimé)") b.bar(x + w / 2, ap["coef"] * 100, w, color=palette.cat[1], label="stigmate × après (estimé)") b.errorbar(x - w / 2, av["coef"] * 100, yerr=1.96 * av["se"] * 100, fmt="none", ecolor=palette.ink2, elinewidth=0.9, capsize=2) b.errorbar(x + w / 2, ap["coef"] * 100, yerr=1.96 * ap["se"] * 100, fmt="none", ecolor=palette.ink2, elinewidth=0.9, capsize=2) b.plot(x - w / 2, av["verite"] * 100, marker="_", color=palette.ink, markersize=12, markeredgewidth=1.8, linestyle="none", label="déclaré", zorder=4) b.plot(x + w / 2, ap["verite"] * 100, marker="_", color=palette.ink, markersize=12, markeredgewidth=1.8, linestyle="none", zorder=4) b.set_xticks(x); b.set_xticklabels([c.replace(" ", "\n") for c in cl], fontsize=7.5); b.axhline(0, color=palette.ink2, linewidth=0.8) b.set_ylabel("Effet sur ln P (points de pourcentage)"); b.set_title("(b) Par classe d'exposition", loc="left"); b.legend(loc="lower right", fontsize=7) fig.tight_layout() savefig(fig, "ch43/ch43-fig-effets-methodes.pdf") if __name__ == "__main__": main()