1

Ajoute jalons et variantes de heatmaps normalisées à l'étape 15

This commit is contained in:
2025-12-01 23:18:02 +01:00
parent 7a193136e5
commit 7fe02ea263
3 changed files with 46 additions and 10 deletions

View File

@@ -7,6 +7,7 @@ import matplotlib.pyplot as plt
import numpy as np
from lib.filesystem import ensure_parent_dir
from lib.milestones import load_milestones
from lib.rebrickable.stats import read_rows
@@ -15,31 +16,63 @@ def load_rows(path: Path) -> List[dict]:
return read_rows(path)
def plot_translucent_share(timeline_path: Path, destination_path: Path) -> None:
"""Trace l'évolution de la part de pièces translucides et du nombre de couleurs."""
def plot_translucent_share(timeline_path: Path, milestones_path: Path, destination_path: Path) -> None:
"""Trace l'évolution de la part de pièces translucides et du nombre de couleurs avec jalons."""
rows = load_rows(timeline_path)
milestones = load_milestones(milestones_path)
years = [int(row["year"]) for row in rows]
shares = [float(row["share_translucent"]) for row in rows]
distinct_counts = [int(row["colors_distinct"]) for row in rows]
fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(years, shares, color="#1f77b4", marker="o", linewidth=2.2, label="Part des translucides")
ax.fill_between(years, shares, color="#1f77b4", alpha=0.15)
fig, ax = plt.subplots(figsize=(13, 5.5))
ax.plot(years, shares, color="#1f77b4", marker="o", linewidth=2.2, label="Part des translucides", zorder=3)
ax.fill_between(years, shares, color="#1f77b4", alpha=0.15, zorder=2)
ax.set_ylabel("Part translucide")
ax.set_ylim(0, min(1.0, max(shares) * 1.1))
ax.set_xlabel("Année")
ax.grid(True, linestyle="--", alpha=0.3)
ax2 = ax.twinx()
ax2.plot(years, distinct_counts, color="#ff7f0e", marker="s", linewidth=1.8, label="Couleurs distinctes")
ax2.plot(years, distinct_counts, color="#ff7f0e", marker="s", linewidth=1.8, label="Couleurs distinctes", zorder=3)
ax2.set_ylabel("Nombre de couleurs distinctes")
handles = [
plt.Line2D([0], [0], color="#1f77b4", marker="o", label="Part des translucides"),
plt.Line2D([0], [0], color="#ff7f0e", marker="s", label="Couleurs distinctes"),
]
ax.legend(handles=handles, loc="upper left")
ax.legend(handles=handles, loc="upper left", bbox_to_anchor=(1.02, 1))
ax.set_title("Evolution des palettes : translucides vs. diversité des couleurs")
ax.set_xticks(years)
ax.tick_params(axis="x", labelrotation=45)
if milestones:
min_year = min(years)
max_year = max(years)
milestones_in_range = sorted(
[m for m in milestones if min_year <= m["year"] <= max_year],
key=lambda m: (m["year"], m["description"]),
)
offset_step = 0.35
offset_map: Dict[int, int] = {}
top_limit = ax.get_ylim()[1] * 1.05
for milestone in milestones_in_range:
year = milestone["year"]
count_for_year = offset_map.get(year, 0)
offset_map[year] = count_for_year + 1
horizontal_offset = offset_step * (count_for_year // 2 + 1)
if count_for_year % 2 == 1:
horizontal_offset *= -1
text_x = year + horizontal_offset
ax.axvline(year, color="#d62728", linestyle="--", linewidth=1, alpha=0.65, zorder=1)
ax.text(
text_x,
top_limit,
milestone["description"],
rotation=90,
verticalalignment="top",
horizontalalignment="center",
fontsize=8,
color="#d62728",
)
ax.set_ylim(ax.get_ylim()[0], top_limit * (1 + max(offset_map.values(), default=0) * 0.02))
ensure_parent_dir(destination_path)
fig.tight_layout()
fig.savefig(destination_path, dpi=160)