SPB Git
2.8 KB · 41 lines python
1#!/usr/bin/env python32"""Figure ch21 — sensibilité du coût neuf du sujet du cas 1 (DONNÉES SYNTHÉTIQUES) : (a) grille taux d'indirects × taux d'incitatif ;3(b) tornade (indirects, incitatif, indice de coûts). Sortie : assets/figures/ch21/ch21-fig-sensibilite.pdf"""4import sys, pathlib5ROOT = pathlib.Path(__file__).resolve().parents[3]6sys.path.insert(0, str(ROOT / "analysis/python")); sys.path.insert(0, str(ROOT / "analysis/python/cases"))7import numpy as np, matplotlib.pyplot as plt8from traite.style import setup, palette, savefig, LARGEUR, fmt_dollars9import ch21_cout_neuf as cas1011def main():12    setup()13    devis, sujet = cas.charger(); cn = cas.cout_neuf_sujet(devis)14    ti = np.array([0.12, 0.15, 0.18, cn["taux_indirects"], 0.24, 0.27]); tc = np.array([0.05, 0.08, 0.10, 0.12, 0.15])15    G = cas.grille_sensibilite(cn["direct"], ti, tc)16    ipcb = cas.ipcb_montreal(); mi = "Maison individuelle [621112]"17    var = cas.indice(ipcb, mi, "2026-07") / cas.indice(ipcb, mi, "2025-07") - 118    torn = cas.tornade(cn["direct"], cn["taux_indirects"], cas.TAUX_INCITATIF, (1 / (1 + var), 1 + var), (-0.05, -0.20))[:3]19    fig, (a, b) = plt.subplots(1, 2, figsize=(LARGEUR, 3.3), gridspec_kw={"width_ratios": [1.15, 1]})20    im = a.imshow(G / 1000, cmap=palette.cmap_seq(), aspect="auto", origin="lower")21    a.set_xticks(range(len(tc))); a.set_xticklabels([f"{x*100:.0f} %" for x in tc]); a.set_yticks(range(len(ti))); a.set_yticklabels([f"{x*100:.1f} %" for x in ti])22    a.set_xlabel("Taux d'incitatif (sur directs + indirects)"); a.set_ylabel("Taux d'indirects (sur directs)"); a.grid(False)23    for i in range(len(ti)):24        for j in range(len(tc)):25            a.text(j, i, f"{G[i, j]/1000:.0f}", ha="center", va="center", fontsize=7.5, color="white" if G[i, j] > G.mean() else palette.ink)26    a.set_title("(a) Coût neuf (milliers de $)", loc="left")27    base = torn[0]["base"]28    for k, o in enumerate(torn):29        lo, hi = min(o["bas"], o["haut"]), max(o["bas"], o["haut"])30        b.barh(k, lo - base, left=base, color=palette.cat[0], height=0.55); b.barh(k, hi - base, left=base, color=palette.cat[1], height=0.55)31        b.text(lo - 1500, k, fmt_dollars(lo), ha="right", va="center", fontsize=7.2); b.text(hi + 1500, k, fmt_dollars(hi), ha="left", va="center", fontsize=7.2)32    b.set_yticks(range(len(torn))); b.set_yticklabels([f"{o['param']}\n({o['etiquette']})" for o in torn], fontsize=7.5)33    b.axvline(base, color=palette.ink, lw=0.8); b.set_xlim(base - 62000, base + 62000)34    b.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f"{x/1000:.0f} k$")); b.grid(axis="y", visible=False)35    b.set_title("(b) Tornade autour de " + fmt_dollars(base), loc="left")36    fig.tight_layout(w_pad=2.0)37    out = savefig(fig, "ch21/ch21-fig-sensibilite.pdf"); print("OK", out)3839if __name__ == "__main__":40    main()41
Files · 389e91a727c101832cccbfb4f596baebb72913c7
Menu

Theme