Projet Matplotlib

Cette page contient les détails d'un projet de rédaction technique accepté pour la saison des documents Google.

Résumé du projet

Organisation Open Source:
Matplotlib
Rédacteur technique:
brunobeltran
Nom du projet:
Améliorer la visibilité des fonctionnalités en standardisant la documentation des types "implicites"
Durée du projet:
Longue durée (5 mois)

Project description

Motivation

Auparavant, l'API de matplotlib s'appuyait fortement sur des "types implicites" sous forme de chaîne en tant qu'énumération. En plus d'imiter l'API de MatLab, ces chaînes de paramètres permettent à l'utilisateur de transmettre des valeurs sémantiquement riches en tant qu'arguments aux fonctions matplotlib sans avoir à importer explicitement ni à ajouter un préfixe de manière détaillée une valeur d'énumération réelle simplement pour transmettre des options de tracé de base (par exemple, plt.plot(x, y, linestyle='solid') est plus facile à saisir et moins redondant que plt.plot(x, y, linestyle=mpl.LineStyle.solid)).

Depuis, de nombreux types implicites de chaîne en tant qu'énumération ont évolué vers des fonctionnalités plus sophistiquées. Par exemple, un linestyle peut désormais être une chaîne ou un tuple à deux éléments de séquences, et un MarkerStyle peut désormais être une chaîne ou un matplotlib.path.Path. Bien que cela soit vrai pour de nombreux types implicites, MarkerStyle est le seul (à ma connaissance) à avoir été mis à niveau en tant que classe Python appropriée.

Étant donné que ces types implicites ne sont pas des classes à part entière, Matplotlib a toujours dû mettre en place ses propres solutions pour centraliser la documentation et la validation de ces types implicites (par exemple, le modèle d'interpolation de la docstring docstring.interpd.update et le modèle de validation cbook._check_in_list, respectivement) au lieu d'utiliser les chaînes d'outils standards fournies par les classes Python (par exemple, les docstrings et le modèle validate-at-__init__, respectivement).

Bien que ces solutions aient bien fonctionné pour nous, l'absence d'emplacement explicite pour documenter chaque type implicite signifie que la documentation est souvent difficile à trouver. De grandes tables de valeurs autorisées sont répétées tout au long de la documentation, et il manque souvent complètement une déclaration explicite du champ d'application d'un type implicite dans la documentation. Prenons les documents plt.plot, par exemple. Dans la section ""Notes"", une description de la méthode de stylisation de la chaîne de format semblable à Matlab mentionne les options linestyle, color et markers. Il existe bien plus de façons de transmettre ces trois valeurs que ce que l'article suggère, mais pour de nombreux utilisateurs, il s'agit de leur seule source d'informations sur les valeurs possibles pour ces options jusqu'à ce qu'ils tombent sur l'un des tutoriels pertinents. Le tableau des attributs Line2D est inclus pour tenter de montrer au lecteur les options dont il dispose pour contrôler son tracé. Toutefois, bien que l'entrée linestyle établisse un bon lien vers Line2D.set_linestyle (deux clics requis) où les entrées possibles sont décrites, les entrées color et markers ne le font pas. color est simplement associé à Line2D.set_color, qui n'offre aucune intuition sur les types d'entrées autorisés.

On pourrait affirmer que ce problème peut être résolu en nettoyant simplement les docstrings individuels qui causent des problèmes, mais le problème est malheureusement beaucoup plus systémique. Sans un emplacement centralisé pour trouver la documentation, nous aurons simplement de plus en plus de copies de documentation de plus en plus détaillée répétées partout où chacun de ces types implicites est utilisé, ce qui rend particulièrement difficile pour les utilisateurs débutants de trouver simplement le paramètre dont ils ont besoin. Cependant, le système actuel, qui oblige les utilisateurs à reconstituer lentement leur modèle mental de chaque type implicite en traversant notre documentation ou dans des exemples StackOverflow au coup par coup, n'est pas viable.

Définissez un objectif final

Dans l'idéal, toute mention d'un type implicite doit renvoyer vers une seule page qui décrit toutes les valeurs possibles que ce type peut prendre, triées de la plus simple et courante à la plus avancée ou ésotérique. Au lieu d'utiliser un espace visuel précieux dans la documentation de l'API de niveau supérieur pour énumérer progressivement tous les types d'entrée possibles pour un paramètre particulier, nous pouvons utiliser cet espace pour donner une description claire de l'abstraction de tracé que le paramètre est censé contrôler.

Pour reprendre l'exemple de linestyle, ce que nous voulons dans les documents LineCollection est simplement:

  1. Lien vers les documents complets sur les entrées autorisées (combinaison de celles trouvées dans Line2D.set_linestyle et du tutoriel sur le style de ligne).
  2. Description en termes clairs de ce que le paramètre est censé accomplir. Pour les utilisateurs expérimentés de matplotlib, cela ressort du nom du paramètre, mais ce n'est pas forcément le cas pour les nouveaux utilisateurs.

Dans les documents LineCollection, cela revient à python """""" linestyles: `LineStyle` or list thereof, default: :rc:`lines.linestyle` ('-') A description of whether the stroke used to draw each line in the collection is dashed, dotted or solid, or some combination thereof. """""", où la référence du type LineStyle serait résolue par Sphinx pour pointer vers l'ensemble de documentation unique, faisant autorité et complet, expliquant comment Matplotlib traite les styles de ligne.

Avantages

Voici quelques-unes des fonctionnalités puissantes de cette approche :

  1. Rendre l'étendue complète de ce que chaque fonction est capable de faire évidente en texte brut (sans aucun clic requis).
  2. Rendre l'option par défaut visible (sans clic) La vue de l'option par défaut suffit souvent à rafraîchir la mémoire des utilisateurs qui reviennent.
  3. Faites une description complète des options ""les plus courantes"" et ""les plus faciles"" pour un paramètre facilement accessible lors de la navigation (en un seul clic).
  4. Pour découvrir des fonctionnalités et des modes de saisie plus performants, il vous suffit de faire défiler l'écran vers le bas pour afficher des options plus avancées (toujours en un seul clic).
  5. Fournissez une stratégie centralisée pour associer les documents ""API"" de niveau supérieur aux ""tutoriels"" pertinents.
  6. Évitez l'explosion de la documentation de l'API, où l'examen des nombreuses options possibles pour chaque paramètre rend les docstrings individuelles difficiles à utiliser.

Voici d'autres avantages de cette approche par rapport aux documents actuels:

  1. Les documents sont moins susceptibles de devenir obsolètes en raison de la centralisation.
  2. Canonisation de nombreuses ""normes implicites"" de matplotlib (par exemple, qu'est-ce qu'une ""borne"" par rapport à une ""étendue"") que vous devez actuellement apprendre en lisant le code.
  3. Ce processus met en évidence les problèmes de cohérence de l'API d'une manière qui peut être plus facilement suivi via l'outil de suivi des problèmes GitHub, ce qui contribue à améliorer notre API.
  4. Temps de compilation des documents plus rapides, grâce à une réduction significative de la quantité de texte à analyser.

Implémentation

Les améliorations décrites ci-dessus nécessiteront deux efforts majeurs pour lesquels un rédacteur technique dédié sera inestimable. La première consiste à créer une page de ""tutoriel"" centralisée par type implicite. Pour ce faire, vous devrez collaborer avec l'équipe de développeurs principale afin d'identifier une liste concrète de types implicites dont la documentation serait utile aux utilisateurs (généralement, car ils contiennent des fonctionnalités puissantes et cachées de notre bibliothèque dont la documentation ne se trouve actuellement que dans des tutoriels difficiles à trouver). Pour chaque type implicite, je synthétiserai ensuite les différents tutoriels, documents d'API et pages d'exemple pertinents en une seule source de documentation officielle pouvant être associée à n'importe quel endroit où ce type particulier est référencé.

Une fois la documentation centralisée d'un type implicite donné terminée, le deuxième effort majeur commence: remplacer la documentation de l'API existante par des liens vers la nouvelle documentation, dans le but de rendre l'utilisation de cette nouvelle documentation aussi simple que possible, à la fois pour ceux qui utilisent l'utilitaire help() intégré de Python et pour ceux qui parcourent notre documentation en ligne.

Bien que le format exact de la documentation proposée ici soit susceptible d'évoluer à mesure que ce projet évolue, j'ai travaillé avec l'équipe de base de Matplotlib lors de leurs ""appels de développement"" hebdomadaires pour établir un consensus selon lequel la stratégie proposée ici est l'approche la plus rapide, utile et techniquement abordable pour commencer à documenter ces ""types implicites"" (des notes sur ces appels sont disponibles sur hackmd). Je vais utiliser l'""infrastructure de tutoriels"" existante pour les étapes initiales de la création de la documentation centralisée pour chaque type implicite, ce qui me permettra de référencer facilement ces pages comme suit, sans avoir à créer de nouvelles classes publiques (encore une fois, en utilisant la documentation LineCollection comme exemple):

""""""
linestyles: LineStyle or list thereof, default: :rc:`lines.linestyle` ('-')
    A description of whether the stroke used to draw each line in the collection
    is dashed, dotted or solid, or some combination thereof. For a full
    description of possible LineStyle's, see :doc:`tutorials/types/linestyle`.
""""""

À l'avenir, nous pourrons facilement modifier l'orthographe de ces références une fois que l'équipe de développeurs principale sera d'accord sur la meilleure stratégie à long terme pour intégrer notre nouvelle documentation sur les ""types"" dans des classes Python authentiques, comme je l'ai proposé dans la proposition d'amélioration 30 de Matplotlib.

Enfin, voici la liste préliminaire des types implicites que je propose de documenter pendant cette saison Google de la documentation:

  1. capstyle
  2. joinstyle
  3. bounds
  4. extents
  5. linestyle
  6. colors/lists of colors
  7. colornorm/colormap
  8. tick formatters

Une version évolutive de ce document est disponible sur Discourse.