cassionAnalyse de données

Retour à la leçonLeçon 8 sur 8Des graphiques qui ne peuvent pas dériver

Le graphique et la phrase viennent du même fichier

Le même diaporama que les téléchargements, rendu sous forme de page. Lancez le diaporama pour le présenter en plein écran — les flèches ou un clic avancent d'une diapositive, Échap quitte.

Diapositives · PDFDiapositives · PowerPoint

  1. Diapositive 1 / 22

    Ce que couvre cette leçon

    • L'échec que cela prévient
    • Ce que fait cette plateforme
    • Les quatre propriétés à copier
    • Le faire sous matplotlib ou ggplot2
    • Ce qu'il faut commiter et ce qu'il faut ignorer
    • L'habitude en trois lignes pour un rapport sans chaîne
    • Rapportez-le en entier
    • La suite
    Notes du présentateur
    Chaque règle de ce cours est une règle dont il faut se souvenir le jour venu. Produire la figure depuis le jeu de données supprime le fait de s'en souvenir — et c'est le seul moyen pour qu'une correction de données déplace le graphique et la phrase ensemble, plutôt que l'un des deux.
  2. Diapositive 2 / 22

    L'échec que cela prévient

    • Rien dans aucune compilation ne peut le détecter — La figure est une image valide, le rapport est un document valide,…
    • Le remède est structurel plutôt que procédural — Si la figure est produite depuis le jeu de données par un script qui…
    Notes du présentateur
    Un graphique est exporté en PNG en mars, collé dans un rapport, et le jeu de données est corrigé en mai. La prose est mise à jour parce que quelqu'un la lit. Le graphique ne l'est pas, parce que personne ne relit une image. Rien dans aucune compilation ne peut le détecter. La figure est une image valide, le rapport est un document valide, et le nombre de la légende et la barre derrière lui sont désormais en désaccord. Le remède est structurel plutôt que procédural. Si la figure est produite depuis le jeu de données par un script qui tourne à chaque compilation, une correction déplace les deux ou aucun, et « penser à régénérer le graphique » cesse d'être une chose dont quiconque doit se souvenir.
  3. Diapositive 3 / 22

    Ce que fait cette plateforme — En Python

    def food_security_instruments() -> Figure:
        survey = read("food-security-survey-2024.v1.csv")
        coping = {row["household_id"]: row for row in read("livelihood-coping-2024.v1.csv")}
    
        # ... compute the four prevalences from the rows ...
    
        return Figure(
            slug="food-security-instruments",
            kind="bar",
            title={"en": "Four instruments, one set of households", "fr": "..."},
            caption={"en": "Four food security instruments applied to the same 1,955 "
                           "households. The highest prevalence is seven times the lowest...",
                     "fr": "..."},
            x_label={"en": "Households flagged (%)", "fr": "Ménages signalés (%)"},
            bars=bars,
        )
    Notes du présentateur
    Chaque figure de ce site est déclarée comme une fonction qui lit un CSV commité et renvoie la description d'un graphique.
  4. Diapositive 4 / 22

    Ce que fait cette plateforme — En R

    # The same shape in R: a function returning data plus its labels, rendered once.
  5. Diapositive 5 / 22

    Ce que fait cette plateforme

    • Aucun nombre n'est saisi — Les 7,4 % de la légende ne sont pas écrits dans la légende — la légende énonce la relation…
    • Deux sorties depuis une description — SVG pour le web, TikZ pour le document PDF et le diaporama Beamer
    • Bibliothèque standard uniquement — Les générateurs n'ont besoin que d'un Python d'origine et d'aucune installation, si…
    Notes du présentateur
    Aucun nombre n'est saisi. Les 7,4 % de la légende ne sont pas écrits dans la légende — la légende énonce la relation et les barres portent les valeurs, toutes calculées depuis le fichier. Deux sorties depuis une description. SVG pour le web, TikZ pour le document PDF et le diaporama Beamer. Une figure écrite une fois apparaît à trois endroits et ne peut pas différer entre eux. Bibliothèque standard uniquement. Les générateurs n'ont besoin que d'un Python d'origine et d'aucune installation, si bien qu'un contributeur peut régénérer chaque figure sans chaîne d'outils.
  6. Diapositive 6 / 22

    Les quatre propriétés à copier

    • Une description, plusieurs rendus — Le graphique est des données plus des étiquettes, et le moteur de rendu est séparé
    • Bilingue par construction — Titre, légende et étiquette d'axe sont des dictionnaires indexés par langue, si bien qu'une…
    • Sortie commitée — Les fichiers SVG et TikZ sont dans le dépôt, si bien que le site se construit sans Python sur le…
    • Un test qui échoue quand ils divergent — figures.test.ts vérifie que chaque figure référencée par une leçon existe,…
    Notes du présentateur
    Quel que soit l'outil employé, voici ce qui fait fonctionner le dispositif. Une description, plusieurs rendus. Le graphique est des données plus des étiquettes, et le moteur de rendu est séparé. C'est ce qui permet à la même figure d'être un SVG web, un vectoriel d'impression et une diapositive sans trois fichiers qui dérivent. Bilingue par construction. Titre, légende et étiquette d'axe sont des dictionnaires indexés par langue, si bien qu'une figure ne peut pas exister dans une seule. La règle de parité de traduction de la plateforme atteint les figures pour la même raison qu'elle atteint les leçons. Sortie commitée. Les fichiers SVG et TikZ sont dans le dépôt, si bien que le site se construit sans Python sur le chemin de déploiement et qu'un contributeur sans la chaîne d'outils peut quand même livrer un changement de contenu. Un test qui échoue quand ils divergent. figures.test.ts vérifie que chaque figure référencée par une leçon existe, qu'une leçon française référence la figure française, que chaque figure existe dans les deux langues et les deux formats, et qu'aucune légende ne fait moins de vingt caractères.
  7. Diapositive 7 / 22

    Les quatre propriétés à copier — En Python

    # The check that matters most, in one line:
    assert (OUT / f"{figure.slug}.{locale}.svg").exists()
  8. Diapositive 8 / 22

    Les quatre propriétés à copier — En R

    # A test is what turns a convention into a constraint.
  9. Diapositive 9 / 22

    Le faire sous matplotlib ou ggplot2 — En Python (suite)

    import pathlib
    import pandas as pd
    import matplotlib.pyplot as plt
    
    FIGURES = pathlib.Path("outputs/figures")
    
    def gam_by_commune() -> None:
        screening = pd.read_csv("data/muac-screening-artibonite-2024.v1.csv")
        summary = (screening.assign(case=screening["muac_mm"] < 125)
                   .groupby("commune")["case"].agg(["mean", "size"])
                   .sort_values("mean"))
    
        fig, ax = plt.subplots(figsize=(6.5, 4))
        ax.barh(summary.index, summary["mean"])
        ax.set_xlabel("GAM (%)")
        fig.savefig(FIGURES / "gam-by-commune.svg", bbox_inches="tight")
    Notes du présentateur
    La même discipline, sans la machinerie de cette plateforme.
  10. Diapositive 10 / 22

    Le faire sous matplotlib ou ggplot2 — En Python (suite)

        plt.close(fig)
    
        summary.to_csv(FIGURES / "gam-by-commune.csv")     # the numbers, beside the chart
    
    if __name__ == "__main__":
        FIGURES.mkdir(parents=True, exist_ok=True)
        gam_by_commune()
  11. Diapositive 11 / 22

    Le faire sous matplotlib ou ggplot2 — En R

    gam_by_commune <- function() {
      summary <- screening |>
        mutate(case = muac_mm < 125) |>
        summarise(gam = mean(case), n = n(), .by = commune)
    
      ggsave("outputs/figures/gam-by-commune.svg", width = 6.5, height = 4)
      write_csv(summary, "outputs/figures/gam-by-commune.csv")
    }
  12. Diapositive 12 / 22

    Le faire sous matplotlib ou ggplot2

    • Écrivez les nombres à côté du graphique — Un CSV auprès de chaque figure est ce qui permet à un relecteur de vérifier…
    • Une fonction par figure, un script qui les lance toutes — Non un carnet où le graphique est la cellule 34 et dépend de…
    • Enregistrez en SVG, non en PNG — partout où la destination le permet : il reste net quand quelqu'un le redimensionne,…
    Notes du présentateur
    Écrivez les nombres à côté du graphique. Un CSV auprès de chaque figure est ce qui permet à un relecteur de vérifier le graphique sans relancer l'analyse, et ce qui permet de vérifier la légende contre quelque chose. Une fonction par figure, un script qui les lance toutes. Non un carnet où le graphique est la cellule 34 et dépend de l'exécution de la cellule 12. Enregistrez en SVG, non en PNG, partout où la destination le permet : il reste net quand quelqu'un le redimensionne, et c'est du texte, donc il se compare.
  13. Diapositive 13 / 22

    Ce qu'il faut commiter et ce qu'il faut ignorer

    CommiterIgnorer
    Le script générateurLes aperçus PNG exportés
    La sortie des figures, si la compilation ne peut pas exécuter PythonLes points de reprise de carnets
    Le CSV des nombres auprès de chaque figureTout ce qui contient un horodatage
  14. Diapositive 14 / 22

    Ce qu'il faut commiter et ce qu'il faut ignorer

    • Sortie déterministe ou rien — Une figure qui incorpore la date de production change à chaque exécution, et le diff…
    Notes du présentateur
    Sortie déterministe ou rien. Une figure qui incorpore la date de production change à chaque exécution, et le diff devient un bruit qui cache un vrai changement. Cette plateforme fixe SOURCE_DATE_EPOCH exactement pour cette raison, et les figures ne portent aucune date.
  15. Diapositive 15 / 22

    L'habitude en trois lignes pour un rapport sans chaîne

    • Un script qui produit chaque figure du rapport — lancé avant l'envoi du rapport, en une seule commande
    • Aucun graphique fait à la main dans un tableur — parce que c'est celui qui ne sera pas régénéré
    • La légende produite avec la figure — ou au moins les nombres qu'elle contient lus depuis le même objet que celui d'où…
    Notes du présentateur
    La plupart des travaux de programme n'ont pas de chaîne de figures et n'en auront pas. La version minimale viable vaut quand même la peine. Un script qui produit chaque figure du rapport, lancé avant l'envoi du rapport, en une seule commande. Aucun graphique fait à la main dans un tableur, parce que c'est celui qui ne sera pas régénéré. La légende produite avec la figure, ou au moins les nombres qu'elle contient lus depuis le même objet que celui d'où le graphique a été tracé.
  16. Diapositive 16 / 22

    L'habitude en trois lignes pour un rapport sans chaîne — En Python

    caption = (f"Global acute malnutrition by commune, {summary['size'].sum():,} children "
               f"screened. {(summary['mean'] > 0.10).sum()} of {len(summary)} communes "
               f"are above the 10% emergency threshold.")
  17. Diapositive 17 / 22

    L'habitude en trois lignes pour un rapport sans chaîne — En R

    # If the caption is an f-string, it cannot disagree with the chart.
  18. Diapositive 18 / 22

    L'habitude en trois lignes pour un rapport sans chaîne

    • Cette seule ligne représente l'essentiel du bénéfice — Une légende calculée depuis les données est une légende qui ne…
    Notes du présentateur
    Cette seule ligne représente l'essentiel du bénéfice. Une légende calculée depuis les données est une légende qui ne peut pas survivre à une correction du jeu de données sans être corrigée elle aussi.
  19. Diapositive 19 / 22

    Rapportez-le en entier — Exemple

    Figure production for this report
    
      All figures are generated from the committed dataset files by
      scripts/figures.py, run as part of the report build. No figure is drawn by
      hand and no number in a caption is typed.
    
      Each figure writes its underlying values to a CSV of the same name, so any
      figure can be checked without rerunning the analysis.
    
      Figures are produced in English and French from one description, so a
      figure cannot exist in only one language.
    
      Output is deterministic: rerunning the script on unchanged data produces
      byte-identical files, so a diff shows only real changes.
  20. Diapositive 20 / 22

    Rapportez-le en entier

    • Le dernier paragraphe est ce qui rend le reste vérifiable — Une chaîne dont la sortie bouge à chaque exécution ne peut…
    Notes du présentateur
    Le dernier paragraphe est ce qui rend le reste vérifiable. Une chaîne dont la sortie bouge à chaque exécution ne peut servir à rien vérifier, et une chaîne dont la sortie est stable transforme « ce graphique est-il à jour ? » en une question à laquelle le système de gestion de versions répond.
  21. Diapositive 21 / 22

    La suite

    • C'est le cours.
    Notes du présentateur
    C'est le cours. Huit leçons et une idée : un graphique est une affirmation, et chaque décision de sa fabrication — la marque, l'intervalle, la palette, l'axe, la légende — est une décision sur ce que cette affirmation dit. Le laboratoire construit deux figures pour un rapport réel à travers une chaîne qui vous appartient, et l'exercice prend un graphique juste dans chacun de ses nombres et trouve les quatre décisions qui l'ont rendu malhonnête quand même.
  22. Diapositive 22 / 22

    La suite

    Lire la leçon complète, avec le code exécutable Retour à la leçon