Nature-grade Figure Composer
Figure est conçue non pas comme un « affichage de résultats », mais comme un moyen de démontrer visuellement une affirmation scientifique. Cette compétence consiste à réorganiser des résultats d'analyse dispersés en une histoire « 1 figure = 1 affirmation », puis à les finaliser dans des fichiers répondant aux spécifications techniques de type Nature.
<SKILL_DIR> est le répertoire contenant ce SKILL.md. Prérequis : Python 3.9+, matplotlib, numpy,
pandas, Pillow, PyMuPDF (pip install pymupdf), scipy (pour les intervalles de confiance à 95%).
Ressources incluses
| Chemin | Contenu | Quand lire |
|---|---|---|
references/guidelines.md | Principes de dessin spécifiés par l'utilisateur (7 règles), spécifications techniques Nature, checklist finale | Lire avant la planification, relire lors du QA |
references/storyboard.md | Comment regrouper les résultats en figures, modèle de Figure 1, types de mise en page, procédure de conception en mode automatique | Étape 3 |
references/charts.md | Type d'affirmation → forme du graphique, incertitude, axes, représentation de champs (cartes), exemples de code nfig | Étape 3 (choix du format), 5 |
references/captions-tables.md | Méthodes et exemples de légendes, tableaux et matériel supplémentaire | Étape 7 |
scripts/inventory.py | Inventaire des fichiers de résultats + planche contact numérotée | Étape 1 |
scripts/nfig.py | Style, palette de couleurs à signification fixe, étiquettes de panneaux, helpers de dessin, QA automatique | Étapes 4–6 |
scripts/assemble.py | Assemblage multi-panneaux de PDF/SVG/PNG existants en conservant le vecteur | Lorsque des panneaux ne peuvent pas être redessinés |
scripts/check_figure.py | Vérification des spécifications des fichiers finaux + images de simulation de daltonisme | Étape 6 |
scripts/make_table.py | CSV → tableau LaTeX booktabs / Markdown | Étape 7 |
assets/figure_plan_template.md | Modèle de plan de figure | Étape 3 |
assets/style_template.py | Modèle de conventions communes à toutes les figures (noms d'affichage, plages de couleurs, étiquettes d'axes) | Étape 4 |
assets/layout_example.json | Exemple de mise en page pour assemble.py | Lors de l'utilisation d'assemble |
Workflow
Étape 1 — Inventaire des résultats (rapide avant les questions)
python <SKILL_DIR>/scripts/inventory.py <project_root> --sheet paper_figures/_inventory --out paper_figures/_inventory/inventory.md
- Lire
paper_figures/_inventory/contact_sheet_*.pngpour comprendre ce que chaque résultat montre. La colonne « made by / read by » du rapport permet de remonter du graphique au script de génération puis aux données sources (nécessaire pour le redessin). - Lire le manuscrit, le README ou les notes pour saisir la question de recherche, la méthode proposée et l'affirmation.
- Ajouter une observation d'une phrase pour chaque résultat (ex :
#6 benchmark.csv → méthode proposée obtient la meilleure précision sur les 3 jeux de données, +6 pt). Cela servira de matière pour le choix à l'étape 2 et la planification à l'étape 3. - Si aucun résultat n'est trouvé, demander ensemble leur emplacement à l'étape 2.
Étape 2 — Entretien (obligatoire après le lancement de la compétence)
La décision sur la façon de regrouper appartient à l'utilisateur, donc vérifier avant de dessiner. Cependant, si la réponse a déjà été donnée dans le message de lancement, ne pas redemander. S'il existe une AskUserQuestion, l'utiliser ; sinon, poser des questions numérotées sous forme de texte et attendre la réponse. Les options doivent être créées concrètement à partir de l'inventaire de l'étape 1 (avec numéros de fichiers et observations).
- Objet (obligatoire) « Quels résultats voulez-vous regrouper en une seule figure ? »
- Automatique : concevoir la composition des figures de l'ensemble du manuscrit (Fig. 1 à N + SI) à partir de tous les résultats (Recommandé)
- 1–2 groupes candidats créés à partir de l'inventaire (ex : « Comparaison des performances : #1 accuracy_bar, #6 benchmark.csv »)
- Description libre (Autre) : possibilité de spécifier « #1, #4, #6 en une figure »
- Message « Quelle est la chose la plus importante à transmettre dans cette figure ? » — 1–2 messages estimés + automatique
- Taille de publication — 2 colonnes 183 mm (Recommandé) / 1 colonne 89 mm / 1,5 colonne 120–136 mm / Automatique
- Livrables (sélection multiple) — Figure (PDF+SVG+PNG) / Légende (en anglais) / Tableau / Liste des SI candidats
Traitement des réponses :
- Si l'objet (Q1) a été spécifié dans le message de lancement, utiliser les valeurs par défaut pour Q2–Q4 (message estimé, 183 mm, Figure+Légende) et ne poser la question qu'en cas de doute.
- Pour « Automatique » ou les éléments non spécifiés, Claude décide quels résultats adopter, comment les disposer et comment les regrouper. Suivre la « procédure de conception en mode automatique » de
references/storyboard.md. - Si l'utilisateur demande « aller de l'avant sans poser de questions », traiter tous les éléments comme automatiques.
- Le texte dans les figures et la légende sont en anglais par défaut (car la soumission est en anglais). La conversation se déroule dans la langue de l'utilisateur.
Étape 3 — Plan de figure (Storyboard)
Avant d'écrire du code, lire references/storyboard.md et écrire paper_figures/figure_plan.md en utilisant le format de assets/figure_plan_template.md. Inclure :
- Le flux général du manuscrit (What → How → Why → Performance → Impact) et le rôle de chaque figure
- Pour chaque figure : message en une phrase (deviendra le titre de la légende), tableau des panneaux (étiquette / contenu / forme du graphique (choisir dans
references/charts.md§1) / source de données / panneau principal ou support), mosaïque et dimensions, rôle des couleurs - Résultats exclus du corps du texte (destinés aux SI) et justification. Ne pas cacher les limites ou les échecs ; les placer dans un panneau de limites du corps ou dans les SI
- Informations manquantes (n, définition des barres d'erreur, test statistique, unités) listées comme
[AUTHOR TODO]
Présenter le plan dans le chat sous forme de tableau court. En mode automatique ou si la composition correspond aux spécifications de l'utilisateur, passer au dessin sans attendre la confirmation, en ajoutant « le plan peut être modifié plus tard ». Ne s'arrêter pour consultation que si les résultats spécifiés ne soutiennent pas le message ou si les spécifications sont contradictoires.
Étape 4 — Fixer le style commun
- Copier
nfig.pydanspaper_figures/src/(pour que les scripts de figures puissent être réexécutés sans la compétence). - Fixer dans un seul
paper_figures/figure_style.jsonpour l'ensemble du manuscrit la correspondance méthode/condition → couleur/marqueur/type de ligne. La signification des couleurs changeant d'une figure à l'autre oblige le lecteur à relire la légende à chaque fois, donc utiliser ce fichier pour toutes les figures.
import style # paper_figures/src/style.py (le chemin ne dépend pas du lieu d'exécution)
pal = nfig.Palette.load_or_build(style.PALETTE,
proposed=["Ours"], highlight=["SOTA-X"],
baselines=["Base A", "Base B"], references=["Oracle"])
- proposed = couleur d'accent (rouge vermillon à saturation réduite), highlight = une seule méthode de comparaison la plus forte en bleu, autres méthodes de comparaison = nuances de gris + marqueurs/types de ligne, reference (valeur théorique, limite supérieure, niveau de chance) = ligne pointillée noire.
- Les affectations existantes ne changent pas, les nouveaux noms sont ajoutés. Pour des catégories autres que les méthodes (jeux de données, etc.), ne pas réutiliser les mêmes couleurs, mais distinguer par la position, la division des panneaux ou les marqueurs.
- Les « conventions d'affichage » partagées par toutes les figures sont regroupées au même endroit dans
paper_figures/src/style.py(copie deassets/style_template.py) et importées par chaque script de figure : nom dans les données → nom d'affichage ("PISurr (ours)"→"PISurr"), plages de couleurs pour la même quantité (ex :TEMP_LIM = (300, 345),ERR_LIM = (0, 6)), étiquettes d'axes avec unités. Écrire ces conventions séparément pour chaque figure entraînerait des décalages.
Étape 5 — Dessin
En principe, redessiner à partir des données sources avec nfig. L'assemblage de PNG existants ne permet pas d'uniformiser les polices, les largeurs de ligne et les couleurs, et la réduction risque de faire passer le texte sous 5 pt. Choisir la forme du graphique dans references/charts.md.
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent)) # fonctionne quel que soit le lieu d'exécution
import nfig
nfig.use_style() # Arial 7/6 pt, axe 0.5 pt, TrueType 42
fig, axd = nfig.figure("double", 120, mosaic="aab;cde") # dessiner à la taille de publication finale
# ... chaque panneau (recettes de charts.md) ...
nfig.shared_legend(fig, pal.handles(["Ours", "SOTA-X", "Base A"])) # une seule légende pour toute la figure
nfig.label_panels(fig, axd) # appeler à la fin : a, b, c… 8 pt gras, alignés en lignes/colonnes
nfig.save(fig, "paper_figures/fig2") # .pdf/.svg/.png + rapport QA automatique
label_panels finalise (fixe) la mise en page, donc ajouter légendes, annotations et barres de couleur avant.
- 1 figure = 1 script (
paper_figures/src/fig2.py). Assurer la reproductibilité de la lecture des données à la sauvegarde. - Dessiner à la taille finale, ne pas réduire ensuite. Ne pas utiliser
bbox_inches="tight"car cela modifie la largeur. - Placer le panneau principal en plus grand, en haut à gauche ou en haut. Aligner la taille, la plage d'axes et les graduations pour les graphiques de même type.
- Pour les figures dont les lignes ont des types de panneaux différents (bande de schéma / ligne d'images ou cartes / graphiques), ne pas utiliser une seule mosaïque, mais
nfig.figure("double", 120, rows=[("a", 0.8), ("bcdef", 1), ("g", 1)])pour composer ligne par ligne. Avec une seule grille, l'espacement des étiquettes de graduation d'une colonne s'applique aussi aux autres lignes de la même colonne, ce qui peut écraser les images ou les cartes. Si les lignes sont de même type, conserver une seule mosaïque (les bords des colonnes seront alignés). - Pour les champs (température, carte d'erreur, etc.), utiliser
nfig.field(plage de couleurs commune dans style.py) +nfig.colorbar, avec une seule barre de couleur pour la même quantité. Pour les photos et images microscopiques, utilisernfig.image_panel. - Panneaux non redessinables (schémas d'outils externes, images microscopiques, figures dont les données sources sont perdues) :
- En petit nombre, les intégrer avec
nfig.image_panel(ax, path)(deviennent raster). - Pour les assembler en conservant le vecteur, composer les panneaux PDF dessinés avec nfig et les PDF externes en utilisant
scripts/assemble.py(assets/layout_example.json, les chemins sont relatifs au JSON). Dessiner les panneaux nfig aux mêmes dimensions (mm) que la cellule après assemblage pour que le facteur de réduction soit ≈1. Ajuster le ratio des cellules et la hauteur jusqu'à ce que les rapports « text below 5 pt », « below 300 dpi », « cell mostly empty » disparaissent. - Expliquer à l'utilisateur pourquoi le redessin n'a pas été possible et que cela pourrait être corrigé si les données sources étaient disponibles.
- En petit nombre, les intégrer avec
- Intégrité des données : ne pas modifier les valeurs, ne pas sélectionner uniquement les parties favorables, partir de 0 pour les barres, ne pas tronquer les axes pour exagérer les différences. Pour les images, seuls un ajustement uniforme et un recadrage sont autorisés (pas de traitement localisé, de composition, ni d'édition par IA générative).
Étape 6 — QA et boucle de correction (minimum 2 passages)
- Vérification automatique : en complément du rapport de
nfig.save, exécuterpython <SKILL_DIR>/scripts/check_figure.py paper_figures/fig2.pdf. Corriger impérativement toute ERREUR ; ne laisser un AVERTISSEMENT que si intentionnel, en enregistrant la raison. - Inspection visuelle : lire
paper_figures/qa/fig2_preview.png(taille finale équivalente) etfig2_access.png(daltonisme deutéranope, protanope, échelle de gris), et vérifier la checklist finale dereferences/guidelines.md. Vérifier en particulier : le message se transmet-il en 3 secondes ? le panneau principal est-il le plus visible ? la lecture se fait-elle de gauche à droite et de haut en bas ? y a-t-il des chevauchements ou débordements de texte ou de lignes, des défauts d'alignement, des espaces vides inutiles ou un trop grand resserrement ? la distinction est-elle possible en cas de daltonisme ou en niveaux de gris ? - Corriger, régénérer, et vérifier à nouveau. Enfin, se mettre à la place d'un relecteur et se demander : « cette figure et sa légende suffisent-elles à me convaincre du message ? »
Étape 7 — Légende, tableau et livraison
- Écrire la légende dans
paper_figures/captions.mdau format dereferences/captions-tables.md(phrase de titre en gras = message → chaque panneau dans l'ordre → définition des symboles, couleurs et abréviations → n, barres d'erreur, test statistique). - Pour les comparaisons numériques précises, utiliser un tableau :
scripts/make_table.py(booktabs, pas de lignes verticales, seule la meilleure valeur en gras). Pour les données au format long avec une ligne par seed, utiliser--groupbyet--statpour agréger directement en moyenne ± écart-type et n. - Rapport à l'utilisateur : liste des fichiers créés, message et composition de chaque figure, résultats déplacés dans les SI avec justification,
[AUTHOR TODO](informations statistiques non confirmées, etc.), AVERTISSEMENTS conservés avec justification.
Emplacement de sortie (par défaut)
Pour éviter de se mélanger avec les fichiers existants de l'utilisateur (comme figures/) et de les écraser, les sorties sont regroupées dans paper_figures/.
Si l'utilisateur spécifie un autre emplacement, s'y conformer.
paper_figures/
├── figure_plan.md figure_style.json captions.md
├── src/ nfig.py, fig1.py, fig2.py, ...
├── fig1.pdf .svg .png, fig2.*, ...
├── tables/ table1.tex, table1.md
├── qa/ *_preview.png, *_access.png
└── _inventory/ inventory.md, contact_sheet_*.png
En cas d'hésitation
- Décider ce qui est montré en se demandant si cela sert de preuve pour le message. Les résultats qui ne sont pas probants, même s'ils ont demandé beaucoup d'efforts, sont envoyés dans les SI.
- Pour une amélioration numérique, l'accompagner impérativement d'un exemple concret montrant ce qu'elle signifie réellement.
- Ne pas montrer uniquement les meilleurs résultats ; présenter également les conditions d'application, les limites et les échecs, cela renforce la crédibilité du message.
- En cas de doute, choisir la solution la plus concise : réduire le nombre de couleurs, réduire le texte (expliquer dans la légende), partager la légende.