diff --git a/README.md b/README.md index cd1e18d..89a4e05 100644 --- a/README.md +++ b/README.md @@ -352,5 +352,5 @@ Le script lit `data/intermediate/minifigs_by_set.csv`, `data/intermediate/sets_e - `data/intermediate/minifig_character_sets.csv` : apparitions des personnages avec set, identifiant de set, année, possession et fig_num. - `figures/step32/minifig_characters/{personnage}.png` : frise horizontale par personnage, composée des visuels de minifigs dans l’ordre chronologique, annotés avec l’année, le numéro de set (avec `*` si possédé) et l’identifiant de minifig. Les minifigs dont l’image n’est pas disponible sont remplacées par un rectangle neutre pour matérialiser le manque. -- `figures/step32/minifig_heads/{personnage}.png` : même principe mais en utilisant les visuels de têtes (`head.jpg`) pour chaque apparition. +- `figures/step32/minifig_heads/{personnage}.png` : même principe mais en utilisant les visuels de têtes (`head.jpg`) pour chaque apparition, annotés avec l’année, le set (avec `*` si possédé) et le `part_num` de la tête. - Les étiquettes affichent aussi l’identifiant de la minifig (`fig-*`) et un astérisque à côté du set (`set_num*`) lorsqu’il est présent dans la collection. diff --git a/figures/step32/minifig_heads/Alan_Grant.png b/figures/step32/minifig_heads/Alan_Grant.png index 9857091..c51074f 100644 Binary files a/figures/step32/minifig_heads/Alan_Grant.png and b/figures/step32/minifig_heads/Alan_Grant.png differ diff --git a/figures/step32/minifig_heads/Allison_Miles.png b/figures/step32/minifig_heads/Allison_Miles.png index 2d33f5d..226627d 100644 Binary files a/figures/step32/minifig_heads/Allison_Miles.png and b/figures/step32/minifig_heads/Allison_Miles.png differ diff --git a/figures/step32/minifig_heads/Atwater.png b/figures/step32/minifig_heads/Atwater.png index 136c940..2c30cc3 100644 Binary files a/figures/step32/minifig_heads/Atwater.png and b/figures/step32/minifig_heads/Atwater.png differ diff --git a/figures/step32/minifig_heads/Barry.png b/figures/step32/minifig_heads/Barry.png index 8e8aa24..6cc0e00 100644 Binary files a/figures/step32/minifig_heads/Barry.png and b/figures/step32/minifig_heads/Barry.png differ diff --git a/figures/step32/minifig_heads/Ben.png b/figures/step32/minifig_heads/Ben.png index 9597003..a08c32a 100644 Binary files a/figures/step32/minifig_heads/Ben.png and b/figures/step32/minifig_heads/Ben.png differ diff --git a/figures/step32/minifig_heads/Brooklynn.png b/figures/step32/minifig_heads/Brooklynn.png index f45f21f..9553cbb 100644 Binary files a/figures/step32/minifig_heads/Brooklynn.png and b/figures/step32/minifig_heads/Brooklynn.png differ diff --git a/figures/step32/minifig_heads/Claire_Dearing.png b/figures/step32/minifig_heads/Claire_Dearing.png index 1bc71a8..218d3fb 100644 Binary files a/figures/step32/minifig_heads/Claire_Dearing.png and b/figures/step32/minifig_heads/Claire_Dearing.png differ diff --git a/figures/step32/minifig_heads/Danny_Nedermeyer.png b/figures/step32/minifig_heads/Danny_Nedermeyer.png index f48b1c8..fc26af9 100644 Binary files a/figures/step32/minifig_heads/Danny_Nedermeyer.png and b/figures/step32/minifig_heads/Danny_Nedermeyer.png differ diff --git a/figures/step32/minifig_heads/Darius.png b/figures/step32/minifig_heads/Darius.png index 4b13071..fc24599 100644 Binary files a/figures/step32/minifig_heads/Darius.png and b/figures/step32/minifig_heads/Darius.png differ diff --git a/figures/step32/minifig_heads/Dennis_Nedry.png b/figures/step32/minifig_heads/Dennis_Nedry.png index f8ce532..95960ad 100644 Binary files a/figures/step32/minifig_heads/Dennis_Nedry.png and b/figures/step32/minifig_heads/Dennis_Nedry.png differ diff --git a/figures/step32/minifig_heads/Duncan_Kincaid.png b/figures/step32/minifig_heads/Duncan_Kincaid.png index d98c854..dff263b 100644 Binary files a/figures/step32/minifig_heads/Duncan_Kincaid.png and b/figures/step32/minifig_heads/Duncan_Kincaid.png differ diff --git a/figures/step32/minifig_heads/Eli_Mills.png b/figures/step32/minifig_heads/Eli_Mills.png index 5e4f745..d6ab6f8 100644 Binary files a/figures/step32/minifig_heads/Eli_Mills.png and b/figures/step32/minifig_heads/Eli_Mills.png differ diff --git a/figures/step32/minifig_heads/Ellie_Sattler.png b/figures/step32/minifig_heads/Ellie_Sattler.png index 4bbf02c..b07357b 100644 Binary files a/figures/step32/minifig_heads/Ellie_Sattler.png and b/figures/step32/minifig_heads/Ellie_Sattler.png differ diff --git a/figures/step32/minifig_heads/Franklin_Webb.png b/figures/step32/minifig_heads/Franklin_Webb.png index 463849a..1afbab6 100644 Binary files a/figures/step32/minifig_heads/Franklin_Webb.png and b/figures/step32/minifig_heads/Franklin_Webb.png differ diff --git a/figures/step32/minifig_heads/Gray_Mitchell.png b/figures/step32/minifig_heads/Gray_Mitchell.png index fd78974..ff47567 100644 Binary files a/figures/step32/minifig_heads/Gray_Mitchell.png and b/figures/step32/minifig_heads/Gray_Mitchell.png differ diff --git a/figures/step32/minifig_heads/Gunnar_Eversol.png b/figures/step32/minifig_heads/Gunnar_Eversol.png index 45a95f8..3d2525e 100644 Binary files a/figures/step32/minifig_heads/Gunnar_Eversol.png and b/figures/step32/minifig_heads/Gunnar_Eversol.png differ diff --git a/figures/step32/minifig_heads/Henry_Loomis.png b/figures/step32/minifig_heads/Henry_Loomis.png index 5af6a1b..6adfcd8 100644 Binary files a/figures/step32/minifig_heads/Henry_Loomis.png and b/figures/step32/minifig_heads/Henry_Loomis.png differ diff --git a/figures/step32/minifig_heads/Henry_Wu.png b/figures/step32/minifig_heads/Henry_Wu.png index feadc4d..49a4d44 100644 Binary files a/figures/step32/minifig_heads/Henry_Wu.png and b/figures/step32/minifig_heads/Henry_Wu.png differ diff --git a/figures/step32/minifig_heads/Hudson_Harper.png b/figures/step32/minifig_heads/Hudson_Harper.png index b5e7aed..d9294ec 100644 Binary files a/figures/step32/minifig_heads/Hudson_Harper.png and b/figures/step32/minifig_heads/Hudson_Harper.png differ diff --git a/figures/step32/minifig_heads/Ian_Malcolm.png b/figures/step32/minifig_heads/Ian_Malcolm.png index 764a51e..d95ce3d 100644 Binary files a/figures/step32/minifig_heads/Ian_Malcolm.png and b/figures/step32/minifig_heads/Ian_Malcolm.png differ diff --git a/figures/step32/minifig_heads/Isabella_Delgado.png b/figures/step32/minifig_heads/Isabella_Delgado.png index dfbdea6..dfea137 100644 Binary files a/figures/step32/minifig_heads/Isabella_Delgado.png and b/figures/step32/minifig_heads/Isabella_Delgado.png differ diff --git a/figures/step32/minifig_heads/John_Hammond.png b/figures/step32/minifig_heads/John_Hammond.png index f779c13..78a0df6 100644 Binary files a/figures/step32/minifig_heads/John_Hammond.png and b/figures/step32/minifig_heads/John_Hammond.png differ diff --git a/figures/step32/minifig_heads/Kayla_Watts.png b/figures/step32/minifig_heads/Kayla_Watts.png index 11a74bc..91a7f47 100644 Binary files a/figures/step32/minifig_heads/Kayla_Watts.png and b/figures/step32/minifig_heads/Kayla_Watts.png differ diff --git a/figures/step32/minifig_heads/Ken_Wheatley.png b/figures/step32/minifig_heads/Ken_Wheatley.png index 644603b..c576c50 100644 Binary files a/figures/step32/minifig_heads/Ken_Wheatley.png and b/figures/step32/minifig_heads/Ken_Wheatley.png differ diff --git a/figures/step32/minifig_heads/Kenji.png b/figures/step32/minifig_heads/Kenji.png index 64ce6ec..cef8c31 100644 Binary files a/figures/step32/minifig_heads/Kenji.png and b/figures/step32/minifig_heads/Kenji.png differ diff --git a/figures/step32/minifig_heads/LeClerc.png b/figures/step32/minifig_heads/LeClerc.png index 929c135..bc608e4 100644 Binary files a/figures/step32/minifig_heads/LeClerc.png and b/figures/step32/minifig_heads/LeClerc.png differ diff --git a/figures/step32/minifig_heads/Lex_Murphy.png b/figures/step32/minifig_heads/Lex_Murphy.png index 332b1f6..a27b699 100644 Binary files a/figures/step32/minifig_heads/Lex_Murphy.png and b/figures/step32/minifig_heads/Lex_Murphy.png differ diff --git a/figures/step32/minifig_heads/Maisie_Lockwood.png b/figures/step32/minifig_heads/Maisie_Lockwood.png index 17125c9..037cf68 100644 Binary files a/figures/step32/minifig_heads/Maisie_Lockwood.png and b/figures/step32/minifig_heads/Maisie_Lockwood.png differ diff --git a/figures/step32/minifig_heads/Martin_Krebs.png b/figures/step32/minifig_heads/Martin_Krebs.png index a732bdc..d8beacb 100644 Binary files a/figures/step32/minifig_heads/Martin_Krebs.png and b/figures/step32/minifig_heads/Martin_Krebs.png differ diff --git a/figures/step32/minifig_heads/Owen_Grady.png b/figures/step32/minifig_heads/Owen_Grady.png index 56e040a..8cbeca6 100644 Binary files a/figures/step32/minifig_heads/Owen_Grady.png and b/figures/step32/minifig_heads/Owen_Grady.png differ diff --git a/figures/step32/minifig_heads/Rainn_DeLaCourt.png b/figures/step32/minifig_heads/Rainn_DeLaCourt.png index 269e384..42c91ad 100644 Binary files a/figures/step32/minifig_heads/Rainn_DeLaCourt.png and b/figures/step32/minifig_heads/Rainn_DeLaCourt.png differ diff --git a/figures/step32/minifig_heads/Ray_Arnold.png b/figures/step32/minifig_heads/Ray_Arnold.png index 0bfa406..5346437 100644 Binary files a/figures/step32/minifig_heads/Ray_Arnold.png and b/figures/step32/minifig_heads/Ray_Arnold.png differ diff --git a/figures/step32/minifig_heads/Reuben_Delgado.png b/figures/step32/minifig_heads/Reuben_Delgado.png index d1a1dfa..4319968 100644 Binary files a/figures/step32/minifig_heads/Reuben_Delgado.png and b/figures/step32/minifig_heads/Reuben_Delgado.png differ diff --git a/figures/step32/minifig_heads/Robert_Muldoon.png b/figures/step32/minifig_heads/Robert_Muldoon.png index 136b47d..98a5bb1 100644 Binary files a/figures/step32/minifig_heads/Robert_Muldoon.png and b/figures/step32/minifig_heads/Robert_Muldoon.png differ diff --git a/figures/step32/minifig_heads/Sammy.png b/figures/step32/minifig_heads/Sammy.png index c429266..d7e87f5 100644 Binary files a/figures/step32/minifig_heads/Sammy.png and b/figures/step32/minifig_heads/Sammy.png differ diff --git a/figures/step32/minifig_heads/Simon_Masrani.png b/figures/step32/minifig_heads/Simon_Masrani.png index 36e2089..2000e7b 100644 Binary files a/figures/step32/minifig_heads/Simon_Masrani.png and b/figures/step32/minifig_heads/Simon_Masrani.png differ diff --git a/figures/step32/minifig_heads/Sinjin_Prescott.png b/figures/step32/minifig_heads/Sinjin_Prescott.png index a09d28d..04576d0 100644 Binary files a/figures/step32/minifig_heads/Sinjin_Prescott.png and b/figures/step32/minifig_heads/Sinjin_Prescott.png differ diff --git a/figures/step32/minifig_heads/Soyona_Santos.png b/figures/step32/minifig_heads/Soyona_Santos.png index 360b500..3bb2ad2 100644 Binary files a/figures/step32/minifig_heads/Soyona_Santos.png and b/figures/step32/minifig_heads/Soyona_Santos.png differ diff --git a/figures/step32/minifig_heads/Teresa_Delgado.png b/figures/step32/minifig_heads/Teresa_Delgado.png index 4ce1d40..de31fc8 100644 Binary files a/figures/step32/minifig_heads/Teresa_Delgado.png and b/figures/step32/minifig_heads/Teresa_Delgado.png differ diff --git a/figures/step32/minifig_heads/Tim_Murphy.png b/figures/step32/minifig_heads/Tim_Murphy.png index 8599c5c..b88e0e3 100644 Binary files a/figures/step32/minifig_heads/Tim_Murphy.png and b/figures/step32/minifig_heads/Tim_Murphy.png differ diff --git a/figures/step32/minifig_heads/Vic_Hoskins.png b/figures/step32/minifig_heads/Vic_Hoskins.png index a8190f7..c30c648 100644 Binary files a/figures/step32/minifig_heads/Vic_Hoskins.png and b/figures/step32/minifig_heads/Vic_Hoskins.png differ diff --git a/figures/step32/minifig_heads/Xavier_Dobbs.png b/figures/step32/minifig_heads/Xavier_Dobbs.png index a06082c..74f7539 100644 Binary files a/figures/step32/minifig_heads/Xavier_Dobbs.png and b/figures/step32/minifig_heads/Xavier_Dobbs.png differ diff --git a/figures/step32/minifig_heads/Yaz.png b/figures/step32/minifig_heads/Yaz.png index 2ff8a27..111f541 100644 Binary files a/figures/step32/minifig_heads/Yaz.png and b/figures/step32/minifig_heads/Yaz.png differ diff --git a/figures/step32/minifig_heads/Zach_Mitchell.png b/figures/step32/minifig_heads/Zach_Mitchell.png index d0363d1..13e36a8 100644 Binary files a/figures/step32/minifig_heads/Zach_Mitchell.png and b/figures/step32/minifig_heads/Zach_Mitchell.png differ diff --git a/figures/step32/minifig_heads/Zia_Rodriguez.png b/figures/step32/minifig_heads/Zia_Rodriguez.png index 5461001..2bdf025 100644 Binary files a/figures/step32/minifig_heads/Zia_Rodriguez.png and b/figures/step32/minifig_heads/Zia_Rodriguez.png differ diff --git a/figures/step32/minifig_heads/Zora_Bennett.png b/figures/step32/minifig_heads/Zora_Bennett.png index bec9612..ed13e5e 100644 Binary files a/figures/step32/minifig_heads/Zora_Bennett.png and b/figures/step32/minifig_heads/Zora_Bennett.png differ diff --git a/lib/plots/minifig_character_collages.py b/lib/plots/minifig_character_collages.py index 46a1b4d..e5029d8 100644 --- a/lib/plots/minifig_character_collages.py +++ b/lib/plots/minifig_character_collages.py @@ -58,6 +58,7 @@ def build_character_collage( font: ImageFont.ImageFont, missing_paths: Set[str] | None = None, image_filename: str = "minifig.jpg", + label_field: str = "fig_num", image_height: int = 260, label_height: int = 44, spacing: int = 28, @@ -69,7 +70,8 @@ def build_character_collage( for row in entries: image_path = resources_dir / row["set_id"] / sanitized / image_filename owned = "*" if row.get("in_collection", "").lower() == "true" else "" - label = f"{row['year']} - {row['set_num']}{owned} ({row['fig_num']})" + label_value = row[label_field] + label = f"{row['year']} - {row['set_num']}{owned} ({label_value})" if str(image_path) in missing: image = build_placeholder(image_height) else: @@ -94,6 +96,7 @@ def build_character_collages( destination_dir: Path, missing_paths: Set[str] | None = None, image_filename: str = "minifig.jpg", + label_field: str = "fig_num", image_height: int = 260, label_height: int = 44, spacing: int = 28, @@ -111,6 +114,7 @@ def build_character_collages( font, missing_paths=missing_paths, image_filename=image_filename, + label_field=label_field, image_height=image_height, label_height=label_height, spacing=spacing, diff --git a/lib/rebrickable/minifig_character_sets.py b/lib/rebrickable/minifig_character_sets.py index 9f5d821..dfac409 100644 --- a/lib/rebrickable/minifig_character_sets.py +++ b/lib/rebrickable/minifig_character_sets.py @@ -28,17 +28,18 @@ def build_character_sets( ) -> List[dict]: """Associe chaque personnage connu aux sets où il apparaît (hors figurants).""" excluded = set(excluded_characters or []) - seen: set[tuple[str, str, str]] = set() + seen: set[tuple[str, str, str, str]] = set() character_sets: List[dict] = [] for row in minifigs_rows: character = row["known_character"].strip() fig_num = row["fig_num"].strip() + part_num = row["part_num"].strip() if character == "" or fig_num == "": continue if character in excluded: continue set_row = sets_lookup[row["set_num"]] - key = (character, row["set_num"], fig_num) + key = (character, row["set_num"], fig_num, part_num) if key in seen: continue character_sets.append( @@ -49,11 +50,12 @@ def build_character_sets( "year": set_row["year"], "fig_num": fig_num, "in_collection": set_row["in_collection"], + "part_num": part_num, } ) seen.add(key) character_sets.sort( - key=lambda row: (row["known_character"], int(row["year"]), row["set_num"], row["fig_num"]) + key=lambda row: (row["known_character"], int(row["year"]), row["set_num"], row["fig_num"], row["part_num"]) ) return character_sets @@ -61,7 +63,7 @@ def build_character_sets( def write_character_sets(destination_path: Path, rows: Sequence[dict]) -> None: """Écrit le CSV listant les sets par personnage.""" ensure_parent_dir(destination_path) - fieldnames = ["known_character", "set_num", "set_id", "year", "fig_num", "in_collection"] + fieldnames = ["known_character", "set_num", "set_id", "year", "fig_num", "in_collection", "part_num"] with destination_path.open("w", newline="") as csv_file: writer = csv.DictWriter(csv_file, fieldnames=fieldnames) writer.writeheader() diff --git a/scripts/plot_minifig_head_collages.py b/scripts/plot_minifig_head_collages.py index e175142..f9e0073 100644 --- a/scripts/plot_minifig_head_collages.py +++ b/scripts/plot_minifig_head_collages.py @@ -36,6 +36,7 @@ def main() -> None: DESTINATION_DIR, missing_paths=missing_heads, image_filename="head.jpg", + label_field="part_num", ) diff --git a/tests/test_minifig_character_collages.py b/tests/test_minifig_character_collages.py index 6be4d4d..5b08be0 100644 --- a/tests/test_minifig_character_collages.py +++ b/tests/test_minifig_character_collages.py @@ -18,12 +18,12 @@ def create_image(path: Path, color: tuple[int, int, int], size: tuple[int, int]) def test_build_character_sets_and_collages(tmp_path: Path) -> None: """Construit les apparitions par personnage puis les frises associées.""" minifigs_rows = [ - {"set_num": "1000-1", "known_character": "Alice", "fig_num": "fig-1"}, - {"set_num": "1000-1", "known_character": "Alice", "fig_num": "fig-1"}, - {"set_num": "1001-1", "known_character": "Bob", "fig_num": "fig-2"}, - {"set_num": "1002-1", "known_character": "Bob", "fig_num": "fig-3"}, - {"set_num": "1004-1", "known_character": "Claire Dearing", "fig_num": "fig-5"}, - {"set_num": "1003-1", "known_character": "Figurant", "fig_num": "fig-4"}, + {"set_num": "1000-1", "known_character": "Alice", "fig_num": "fig-1", "part_num": "p1"}, + {"set_num": "1000-1", "known_character": "Alice", "fig_num": "fig-1", "part_num": "p1"}, + {"set_num": "1001-1", "known_character": "Bob", "fig_num": "fig-2", "part_num": "p2"}, + {"set_num": "1002-1", "known_character": "Bob", "fig_num": "fig-3", "part_num": "p3"}, + {"set_num": "1004-1", "known_character": "Claire Dearing", "fig_num": "fig-5", "part_num": "p5"}, + {"set_num": "1003-1", "known_character": "Figurant", "fig_num": "fig-4", "part_num": "p4"}, ] sets_lookup = { "1000-1": {"set_id": "1000", "year": "2020", "in_collection": "true"}, @@ -42,6 +42,7 @@ def test_build_character_sets_and_collages(tmp_path: Path) -> None: "year": "2020", "fig_num": "fig-1", "in_collection": "true", + "part_num": "p1", }, { "known_character": "Bob", @@ -50,6 +51,7 @@ def test_build_character_sets_and_collages(tmp_path: Path) -> None: "year": "2021", "fig_num": "fig-2", "in_collection": "false", + "part_num": "p2", }, { "known_character": "Bob", @@ -58,6 +60,7 @@ def test_build_character_sets_and_collages(tmp_path: Path) -> None: "year": "2022", "fig_num": "fig-3", "in_collection": "false", + "part_num": "p3", }, { "known_character": "Claire Dearing", @@ -66,6 +69,7 @@ def test_build_character_sets_and_collages(tmp_path: Path) -> None: "year": "2024", "fig_num": "fig-5", "in_collection": "true", + "part_num": "p5", }, ]