1

Reviens à l’état fbf20e2 sans palettes par set

This commit is contained in:
2025-12-02 16:23:56 +01:00
parent 909a1eae71
commit c0700a8829
11 changed files with 0 additions and 816 deletions

View File

@@ -1,89 +0,0 @@
"""Palette dominante par set (hors minifigs)."""
from collections import defaultdict
from pathlib import Path
from typing import Dict, List, Sequence
import matplotlib.pyplot as plt
from lib.filesystem import ensure_parent_dir
from lib.rebrickable.stats import read_rows
PLACEHOLDER_COLOR = "#e0e0e0"
def load_swatches(path: Path) -> List[dict]:
"""Charge le CSV des couleurs dominantes par set."""
return read_rows(path)
def group_swatches(rows: Sequence[dict], top_n: int = 5) -> List[dict]:
"""Groupe les couleurs par set et complète avec des placeholders si besoin."""
grouped: Dict[str, List[dict]] = defaultdict(list)
meta: Dict[str, dict] = {}
for row in rows:
grouped[row["set_num"]].append(row)
meta[row["set_num"]] = {"name": row["name"], "year": int(row["year"])}
result: List[dict] = []
for set_num, colors in grouped.items():
sorted_colors = sorted(colors, key=lambda r: int(r["rank"]))
while len(sorted_colors) < top_n:
sorted_colors.append(
{
"set_num": set_num,
"name": meta[set_num]["name"],
"year": str(meta[set_num]["year"]),
"rank": str(len(sorted_colors) + 1),
"color_rgb": "",
"color_name": "N/A",
"quantity_non_minifig": "0",
}
)
result.append(
{
"set_num": set_num,
"name": meta[set_num]["name"],
"year": meta[set_num]["year"],
"colors": sorted_colors[:top_n],
}
)
result.sort(key=lambda r: (r["year"], r["name"], r["set_num"]))
return result
def plot_set_color_swatches(swatches_path: Path, destination_path: Path) -> None:
"""Trace la palette de 5 couleurs dominantes par set (hors minifigs)."""
rows = load_swatches(swatches_path)
if not rows:
return
grouped = group_swatches(rows, top_n=5)
set_labels = [f"{item['year']} {item['name']}" for item in grouped]
y_positions = list(range(len(grouped)))
height = max(4, len(grouped) * 0.4)
fig, ax = plt.subplots(figsize=(12, height))
for y, item in zip(y_positions, grouped):
for idx, color in enumerate(item["colors"]):
rgb = color["color_rgb"].strip()
face_color = f"#{rgb}" if rgb else PLACEHOLDER_COLOR
ax.scatter(
idx,
y,
s=500,
color=face_color,
edgecolor="#0d0d0d",
linewidth=0.6,
)
ax.set_yticks(y_positions)
ax.set_yticklabels(set_labels)
ax.set_xticks([])
ax.invert_yaxis()
ax.set_xlim(-0.6, 4.6)
ax.set_title("Top 5 couleurs principales par set (hors minifigs)")
ax.grid(False)
ensure_parent_dir(destination_path)
fig.tight_layout()
fig.savefig(destination_path, dpi=160)
plt.close(fig)

View File

@@ -1,93 +0,0 @@
"""Visualisation des palettes perceptuelles (top 5) par set."""
from collections import defaultdict
from pathlib import Path
from typing import Dict, List, Sequence
import matplotlib.pyplot as plt
from lib.filesystem import ensure_parent_dir
from lib.rebrickable.stats import read_rows
PLACEHOLDER_COLOR = "#e0e0e0"
def load_swatches(path: Path) -> List[dict]:
"""Charge le CSV des palettes perceptuelles."""
return read_rows(path)
def group_swatches(rows: Sequence[dict], top_n: int = 5) -> List[dict]:
"""Groupe les couleurs par set et complète avec placeholders si besoin."""
grouped: Dict[str, List[dict]] = defaultdict(list)
meta: Dict[str, dict] = {}
for row in rows:
grouped[row["set_num"]].append(row)
meta[row["set_num"]] = {"name": row["name"], "year": int(row["year"])}
result: List[dict] = []
for set_num, colors in grouped.items():
sorted_colors = sorted(colors, key=lambda r: int(r["rank"]))
while len(sorted_colors) < top_n:
sorted_colors.append(
{
"set_num": set_num,
"name": meta[set_num]["name"],
"year": str(meta[set_num]["year"]),
"rank": str(len(sorted_colors) + 1),
"color_rgb": "",
"color_name": "N/A",
"share_non_minifig": "0",
"quantity_non_minifig": "0",
}
)
result.append(
{
"set_num": set_num,
"name": meta[set_num]["name"],
"year": meta[set_num]["year"],
"colors": sorted_colors[:top_n],
}
)
result.sort(key=lambda r: (r["year"], r["set_num"], r["name"]))
return result
def plot_set_color_swatches_perceptual(swatches_path: Path, destination_path: Path) -> None:
"""Trace les 5 couleurs perceptuelles par set avec taille proportionnelle à la part."""
rows = load_swatches(swatches_path)
if not rows:
return
grouped = group_swatches(rows, top_n=5)
set_labels = [f"{item['year']} {item['name']}" for item in grouped]
y_positions = list(range(len(grouped)))
height = max(4, len(grouped) * 0.4)
fig, ax = plt.subplots(figsize=(12, height))
for y, item in zip(y_positions, grouped):
for idx, color in enumerate(item["colors"]):
rgb = color["color_rgb"].strip()
face_color = f"#{rgb}" if rgb else PLACEHOLDER_COLOR
share = float(color.get("share_non_minifig", "0"))
size = 450 + 900 * share
ax.scatter(
idx,
y,
s=size,
color=face_color,
edgecolor="#0d0d0d",
linewidth=0.6,
alpha=0.95,
)
ax.set_yticks(y_positions)
ax.set_yticklabels(set_labels)
ax.set_xticks([])
ax.invert_yaxis()
ax.set_xlim(-0.6, 4.6)
ax.set_title("Top 5 couleurs perceptuelles par set (hors minifigs, pièces techniques exclues)")
ax.grid(False)
ensure_parent_dir(destination_path)
fig.tight_layout()
fig.savefig(destination_path, dpi=160)
plt.close(fig)