#!/usr/bin/env python3 """Figure ch04 — marché locatif par RMR : taux d'inoccupation (octobre 2024 et 2025) et loyer moyen des logements de deux chambres (octobre 2025), appartements d'initiative privée de trois logements et plus. DONNÉES RÉELLES (citées avec attribution, conditions SCHL) : SCHL, Enquête sur les logements locatifs, octobre 2025, tableaux 1.1.1 et 1.1.2 (data/raw/schl_rml_2025/rmr-quebec-2025-fr.xlsx). Sortie : assets/figures/ch04/ch04-fig-schl-rmr.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 matplotlib.ticker import FuncFormatter from traite.style import setup, palette, savefig, LARGEUR, fmt_dollars import ch04_marches as cas def main(): setup() sc = cas.schl_rmr(); sc.index = [{"Montréal": "Montréal", "Québec": "Québec", "Gatineau (partie du Québec)": "Gatineau\n(partie QC)", "Sherbrooke": "Sher-\nbrooke", "Trois-Rivières": "Trois-\nRivières", "Saguenay": "Sague-\nnay"}[i] for i in sc.index] x = np.arange(len(sc)); w = 0.38 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(LARGEUR, 3.2)) ax1.bar(x - w / 2, sc["inocc_tous_2024"], w, color=palette.cat[1], label="Octobre 2024") ax1.bar(x + w / 2, sc["inocc_tous_2025"], w, color=palette.cat[0], label="Octobre 2025") ax1.axhline(3.0, color=palette.ink2, lw=0.7, ls=":"); ax1.text(-0.45, 3.1, "3 % (seuil de l'art. 11, L.Q. 2024, c. 23)", ha="left", fontsize=6.8, color=palette.ink2) for xi, v in zip(x + w / 2, sc["inocc_tous_2025"]): ax1.text(xi, v + 0.05, f"{v:.1f}".replace(".", ","), ha="center", fontsize=7) ax1.set_xticks(x); ax1.set_xticklabels(sc.index, fontsize=6.8); ax1.set_ylabel("Taux d'inoccupation, tous les logements (%)"); ax1.set_ylim(0, 4.6) ax1.yaxis.set_major_formatter(FuncFormatter(lambda v, p: f"{v:.0f}")); ax1.legend(loc="upper left", fontsize=7, bbox_to_anchor=(0.0, 0.97)) ax2.bar(x, sc["loyer_2_chambres_2025"], 0.6, color=palette.cat[0]) for xi, v in zip(x, sc["loyer_2_chambres_2025"]): ax2.text(xi, v + 15, fmt_dollars(v), ha="center", fontsize=7) ax2.set_xticks(x); ax2.set_xticklabels(sc.index, fontsize=6.8); ax2.set_ylabel("Loyer moyen, deux chambres, octobre 2025 ($/mois)"); ax2.set_ylim(0, 1650) ax2.yaxis.set_major_formatter(FuncFormatter(lambda v, p: f"{v:,.0f}".replace(",", " "))) fig.tight_layout(w_pad=1.2) out = savefig(fig, "ch04/ch04-fig-schl-rmr.pdf"); print("OK", out) if __name__ == "__main__": main()