#!/usr/bin/env python3 """Figure ch23 — IPCB Montréal, maison individuelle, par division de travaux (Statistique Canada 18-10-0289-01), données RÉELLES : variation de l'indice de chaque division entre le T1 2020 et le T4 2022 (flambée) et entre le T3 2025 et le T3 2026 (dernière année). Les divisions sont des indices de prix, non des contributions pondérées (les poids du panier ne sont pas publiés dans le tableau). Sortie : assets/figures/ch23/ch23-fig-ipcb-divisions.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 ch23_structure_couts as cas COURT = {"Bois, plastiques et composites": "Bois, plastiques, composites", "Chauffage, ventilation et conditionnement d’air": "CVCA", "Isolation thermique et étanchéité": "Isolation et étanchéité", "Sécurité et protection électronique": "Sécurité électronique", "Services d’utilités": "Services d'utilités", "Agrégat des divisions": "Ensemble (agrégat)"} def main(): setup() df_div = cas.ipcb_long(("Montréal, Québec",), ("Maison individuelle [621112]",), None) dv = cas.divisions_maison(df_div).iloc[::-1] y = np.arange(len(dv)); h = 0.38 fig, ax = plt.subplots(figsize=(LARGEUR, 4.6)) ax.barh(y + h / 2, dv["var_2020_2022"] * 100, height=h, color=palette.cat[0], label="T1 2020 → T4 2022") ax.barh(y - h / 2, dv["var_aa"] * 100, height=h, color=palette.cat[1], label="T3 2025 → T3 2026") ax.set_yticks(y); ax.set_yticklabels([COURT.get(d, d) for d in dv["division"]], fontsize=7.5) for yi, (a, b, d) in enumerate(zip(dv["var_2020_2022"], dv["var_aa"], dv["division"])): ax.text(a * 100 + 1, yi + h / 2, f"{a*100:+.0f} %", va="center", fontsize=6.8, color=palette.ink) ax.text(b * 100 + 1, yi - h / 2, f"{b*100:+.1f} %", va="center", fontsize=6.8, color=palette.ink) if d == "Agrégat des divisions": ax.get_yticklabels()[yi].set_fontweight("bold") ax.axvline(0, color=palette.ink2, lw=0.6) ax.set_xlabel("Variation de l'indice de division (%)"); ax.set_xlim(-2, 100) ax.legend(loc="lower right", fontsize=7.5) ax.grid(axis="y", visible=False) out = savefig(fig, "ch23/ch23-fig-ipcb-divisions.pdf"); print("OK", out) if __name__ == "__main__": main()