spb/traite-evaluation-qc
Public
1#!/usr/bin/env python32"""Figure ch43 — doubles différences sur les séries de RNE du cas 4 avec choc d'inondation injecté en 2019 (DONNÉES SYNTHÉTIQUES).3(a) ln RNE moyen des trois immeubles traités et des témoins (centré sur 2019T1), vérité sans choc en tireté ;4(b) étude d'événement (effets fixes immeuble + RMR × trimestre), IC à 95 % en grappes, choc déclaré en marches.5Sortie : assets/figures/ch43/ch43-fig-did-cas4.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 ch43_risques as cas121314def main():15 setup()16 pan = cas.panel_choc(); dd = cas.did_cas4(pan)17 idx = dd["idx"]; t_ev = idx[cas.T_EVENEMENT]; t_ref = t_ev - 118 fig, (a, b) = plt.subplots(1, 2, figsize=(LARGEUR, 3.3))19 # (a) trajectoires centrées sur 2019T120 for tr, col, lab in [(0, palette.cat[2], "témoins (45 immeubles)"), (1, palette.cat[0], "traités (3 immeubles en zone inondable)")]:21 g = pan[pan["traite"] == tr].groupby("t")["ln_rne"].mean(); g = g - g.loc[t_ref]22 a.plot(g.index, g.values, color=col, linewidth=1.5, label=lab)23 g0 = pan[pan["traite"] == 1].groupby("t")["ln_rne_sans_choc"].mean(); g0 = g0 - g0.loc[t_ref]24 a.plot(g0.index, g0.values, color=palette.cat[0], linewidth=1.0, linestyle="--", label="traités sans le choc (vérité)")25 a.axvline(t_ev - 0.5, color=palette.ink2, linewidth=0.8, linestyle=":")26 a.text(t_ev + 0.9, -0.24, "inondation\n2019T2", fontsize=7, color=palette.ink2, va="bottom")27 ticks = [idx[q] for q in ["2016Q1", "2018Q1", "2020Q1", "2022Q1", "2024Q1", "2026Q1"]]28 a.set_xticks(ticks); a.set_xticklabels(["2016", "2018", "2020", "2022", "2024", "2026"])29 a.set_ylabel("ln RNE moyen, écart à 2019T1"); a.set_title("(a) Trajectoires", loc="left"); a.legend(loc="upper left", fontsize=7)30 # (b) étude d'événement31 es = dd["event_study"]32 b.fill_between(es.index, es["ic_bas"], es["ic_haut"], color=palette.cat[0], alpha=0.15, linewidth=0)33 b.plot(es.index, es["coef"], marker="o", markersize=3.5, color=palette.cat[0], linewidth=1.2, label="coefficient estimé (réf. k = −1)")34 kk = np.arange(-8, 13); verite = np.zeros(len(kk), float)35 for q, c in cas.CHOC_2019.items(): verite[kk == idx[q] - t_ev] = c36 verite[kk >= idx["2020Q1"] - t_ev] = cas.CHOC_PERMANENT37 b.step(kk, verite, where="mid", color=palette.ink, linewidth=1.0, linestyle="--", label="choc déclaré")38 b.axhline(0, color=palette.ink2, linewidth=0.8); b.axvline(-0.5, color=palette.ink2, linewidth=0.8, linestyle=":")39 b.set_xlabel("Trimestres depuis l'inondation (k)"); b.set_ylabel("Effet sur ln RNE"); b.set_title("(b) Étude d'événement", loc="left")40 b.legend(loc="lower left", fontsize=7)41 fig.tight_layout()42 savefig(fig, "ch43/ch43-fig-did-cas4.pdf")434445if __name__ == "__main__":46 main()47