#!/usr/bin/env python3 """Figure ch42 — valeur de conversion (somme des fractions nette des coûts, des frais, du portage et des délais) selon la rotation annuelle des locataires, pour trois décotes de vente occupée, comparée à la valeur en bloc (DONNÉES SYNTHÉTIQUES, immeuble fictif de 8 logements). Sortie : assets/figures/ch42/ch42-fig-bloc-piece.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() rhos = np.linspace(0.02, 0.40, 39) v_bloc = cas.valeur_bloc()["valeur"] fig, ax = plt.subplots(figsize=(LARGEUR, 3.7)) for i, d in enumerate((0.10, 0.20, 0.30)): v = [cas.faisabilite(rho, d)["v_conv"] for rho in rhos] ax.plot(rhos * 100, v, color=palette.cat[i], lw=1.8, label=f"Attente des départs ; reliquat vendu occupé à l'an 6 avec décote {d:.0%}") vo = cas.faisabilite(cas.ROTATION, d, vendre_occupe=True)["v_conv"] ax.scatter([cas.ROTATION * 100], [vo], color=palette.cat[i], marker="D", s=22, zorder=5) ax.annotate(f"vente occupée dès l'an 1 (δ = {d:.0%})", xy=(cas.ROTATION * 100, vo), xytext=(cas.ROTATION * 100 + 1.5, vo + 6000), fontsize=7, color=palette.ink2) ax.axhline(v_bloc, color=palette.ink2, lw=1.2, ls="--") ax.text(40, v_bloc + 8000, f"Valeur en bloc (RNE / 5@25 %) : {v_bloc:,.0f} $".replace(",", " ").replace("@", ","), ha="right", fontsize=7.8, color=palette.ink) base = cas.faisabilite() ax.scatter([cas.ROTATION * 100], [base["v_conv"]], color=palette.ink, s=26, zorder=6) ax.annotate(f"cas de base : ρ = 12 %@ δ = 20 % → {base['v_conv']:,.0f} $".replace(",", " ").replace("@", ","), xy=(cas.ROTATION * 100, base["v_conv"]), xytext=(cas.ROTATION * 100 + 1.5, base["v_conv"] - 55000), fontsize=7.2, color=palette.ink, arrowprops=dict(arrowstyle="-", color=palette.ink2, lw=0.7)) ax.set_xlabel("Rotation annuelle des locataires ρ (% des logements occupés libérés par année)") ax.set_ylabel("Valeur actualisée à 10 % (dollars de 2026)") ax.yaxis.set_major_formatter(plt.FuncFormatter(fmt_dollars)) ax.set_xlim(0, 41) ax.legend(loc="upper center", bbox_to_anchor=(0.45, -0.2), ncol=1, fontsize=7.3) out = savefig(fig, "ch42/ch42-fig-bloc-piece.pdf"); print("OK", out) if __name__ == "__main__": main()