#!/usr/bin/env python3 """Figure ch42 — charges annuelles normalisées des huit fractions (ch. 7) et part de chacune dans une cotisation spéciale égale au déficit de capitalisation du fonds de prévoyance (DONNÉES SYNTHÉTIQUES, immeuble fictif du ch. 7). Sortie : assets/figures/ch42/ch42-fig-cotisation-speciale.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, fmt_dollars import ch42_copro as cas def main(): setup() cs = cas.cotisation_speciale(); rep = cs["rep"]; qp = cas.QP noms = [f"{n} ({s:.0f} m², q = {q:.4f})".replace(".", ",") for n, s, q in zip(qp["noms"], qp["superficies"], qp["q"])] y = np.arange(len(noms)); h = 0.36 fig, ax = plt.subplots(figsize=(LARGEUR, 3.9)) gauche = np.zeros(len(noms)) blocs = [("Charges courantes", rep["par_fraction_courantes"], palette.cat[0]), ("Fonds de prévoyance (A*)", rep["par_fraction_fonds"], palette.cat[1]), ("Fonds d'auto assurance", rep["par_fraction_auto"], palette.cat[2]), ("Stationnement (usage restreint)", rep["par_fraction_restreint"], palette.cat[3])] for lab, vals, col in blocs: ax.barh(y - h / 2, vals, left=gauche, height=h, color=col, label=lab + " — annuel"); gauche += vals ax.barh(y + h / 2, cs["par_fraction"], height=h, color=palette.surface, edgecolor=palette.cat[4], hatch="////", lw=0.8, label=f"Cotisation spéciale unique = q_i × {cs['montant']:,.0f} $ (déficit du fonds)".replace(",", " ")) for yi, tot, part, ratio in zip(y, rep["par_fraction_total"], cs["par_fraction"], cs["ratio_annees"]): ax.text(tot + 300, yi - h / 2, f"{tot:,.0f} $/an".replace(",", " "), va="center", fontsize=7.2, color=palette.ink) ax.text(part + 300, yi + h / 2, f"{part:,.0f} $ (= {ratio:.1f} années de charges)".replace(",", " ").replace(".", ","), va="center", fontsize=7.2, color=palette.ink) ax.set_yticks(y); ax.set_yticklabels(noms); ax.invert_yaxis() ax.xaxis.set_major_formatter(plt.FuncFormatter(fmt_dollars)); ax.set_xlim(0, cs["par_fraction"].max() * 1.75) ax.set_xlabel("Dollars de 2026 (données synthétiques, immeuble fictif de huit fractions)") ax.grid(axis="y", visible=False) ax.legend(loc="upper center", bbox_to_anchor=(0.45, -0.17), ncol=2, fontsize=7.2) out = savefig(fig, "ch42/ch42-fig-cotisation-speciale.pdf"); print("OK", out) if __name__ == "__main__": main()