1

Ajoute le graphique variations vs total par personnage

This commit is contained in:
2025-12-03 21:50:28 +01:00
parent 3c20b74b1c
commit f9854a6949
7 changed files with 244 additions and 1 deletions

View File

@@ -21,6 +21,11 @@ def load_presence(path: Path) -> List[dict]:
return read_rows(path)
def load_variations_and_totals(path: Path) -> List[dict]:
"""Charge le CSV comparatif variations/total par personnage."""
return read_rows(path)
def plot_minifigs_per_character(counts_path: Path, destination_path: Path) -> None:
"""Trace un diagramme en barres horizontales du nombre de minifigs par personnage."""
rows = load_counts(counts_path)
@@ -68,6 +73,86 @@ def plot_minifigs_per_character(counts_path: Path, destination_path: Path) -> No
plt.close(fig)
def plot_character_variations_vs_total(counts_path: Path, destination_path: Path) -> None:
"""Superpose le total de minifigs et leurs variations distinctes par personnage."""
rows = load_variations_and_totals(counts_path)
if not rows:
return
characters = [row["known_character"] for row in rows]
variation_counts = [int(row["variation_count"]) for row in rows]
total_counts = [int(row["total_minifigs"]) for row in rows]
genders = [row.get("gender", "") for row in rows]
gender_colors = [GENDER_COLORS.get(gender.strip().lower(), GENDER_COLORS["unknown"]) for gender in genders]
positions = list(range(len(rows)))
height = max(6, len(rows) * 0.24)
background_color = "#d7d7e0"
fig, ax = plt.subplots(figsize=(12.4, height))
bars_total = ax.barh(
positions,
total_counts,
color=background_color,
edgecolor="#0d0d0d",
linewidth=0.6,
height=0.6,
label="Total de minifigs",
)
bars_variations = ax.barh(
positions,
variation_counts,
color=gender_colors,
edgecolor="#0d0d0d",
linewidth=0.8,
height=0.36,
label="Variations distinctes",
)
ax.set_yticks(positions)
ax.set_yticklabels(characters)
ax.invert_yaxis()
ax.set_xlabel("Nombre de minifigs")
ax.set_title("Variations et total de minifigs par personnage (hors figurants)")
ax.grid(True, axis="x", linestyle="--", alpha=0.25)
max_value = max(total_counts) if total_counts else 0
ax.set_xlim(0, max_value + 1)
for index, bar in enumerate(bars_total):
value = total_counts[index]
ax.text(value + 0.12, bar.get_y() + bar.get_height() / 2, str(value), va="center", fontsize=8, color="#1a1a1a")
for index, bar in enumerate(bars_variations):
value = variation_counts[index]
ax.text(value + 0.12, bar.get_y() + bar.get_height() / 2, str(value), va="center", fontsize=8, color="#0d0d0d")
legend_entries = [
Patch(facecolor=background_color, edgecolor="#0d0d0d", linewidth=0.6, label="Total de minifigs"),
Patch(
facecolor=GENDER_COLORS["unknown"],
edgecolor="#0d0d0d",
linewidth=0.8,
label="Variations distinctes (couleur = genre)",
),
]
seen = set()
for gender, color in zip(genders, gender_colors):
normalized = gender.strip().lower()
if normalized in seen:
continue
seen.add(normalized)
legend_entries.append(
Patch(
facecolor=color,
edgecolor="#0d0d0d",
linewidth=0.6,
label=GENDER_LABELS.get(normalized, "Inconnu"),
)
)
ax.legend(handles=legend_entries, loc="lower right")
ensure_parent_dir(destination_path)
fig.tight_layout()
fig.savefig(destination_path, dpi=160)
plt.close(fig)
def plot_character_year_presence(presence_path: Path, destination_path: Path) -> None:
"""Trace une heatmap indiquant le nombre de minifigs par personnage et par année."""
rows = load_presence(presence_path)