Projet Matplotlib

Cette page contient les détails d'un projet de rédaction technique accepté pour Google Season of Docs.

Résumé du projet

Organisation Open Source:
Matplotlib
Rédacteur technique:
Brunobeltran
Nom du projet:
Amélioration de la visibilité des caractéristiques en standardisant la documentation des types "implicites"
Durée du projet:
Exécution de longue durée (5 mois)

Project description

Motivation

Historiquement, l'API de matplotlib s'appuyait beaucoup sur les "types implicites" de string-as-enum. En plus d'imiter l'API de Matlab, ces chaînes de paramètres permettent à l'utilisateur de transmettre des valeurs sémantiques riches en tant qu'arguments aux fonctions matplotlib sans avoir à importer ou préfixer explicitement une valeur d'énumération réelle pour transmettre les options de tracé de base (par exemple, plt.plot(x, y, linestyle='solid') est plus facile à saisir et moins redondant que quelque chose comme plt.plot(x, y, linestyle=mpl.LineStyle.solid)).

Un grand nombre de ces types implicites de chaîne en tant qu'énumération ont depuis évolué des fonctionnalités plus sophistiquées. Par exemple, un linestyle peut désormais être une chaîne ou un 2-tuple 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 vers une classe Python appropriée.

Étant donné que ces types implicites ne sont pas des classes à part entière, Matplotlib a historiquement dû déployer ses propres solutions pour centraliser la documentation et la validation de ces types implicites (par exemple, le modèle d'interpolation docstring docstring.interpd.update et le modèle de validateur 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, que de grandes tables de valeurs autorisées sont répétées tout au long de la documentation et qu'il manque souvent complètement une instruction explicite du champ d'application d'un type implicite. Prenons l'exemple des documents plt.plot. Dans "Notes", une description de la méthode de style de chaîne de format de type Matlab mentionne les options linestyle, color et markers. Les méthodes de transmission de ces trois valeurs sont bien plus nombreuses que celles qui sont indiquées, mais pour de nombreux utilisateurs, il s'agit de leur seule source de compréhension des valeurs possibles pour ces options jusqu'à ce qu'ils tombent sur l'un des tutoriels pertinents. La table d'attributs Line2D est incluse pour essayer de montrer au lecteur les options dont il dispose pour contrôler son tracé. Toutefois, bien que l'entrée linestyle fonctionne correctement pour établir une liaison avec Line2D.set_linestyle (deux clics requis) où les entrées possibles sont décrites, ce n'est pas le cas des entrées color et markers. color est simplement associé à Line2D.set_color, qui ne permet même pas d'identifier les types d'entrées autorisés.

On pourrait affirmer que ce problème peut être résolu en nettoyant simplement les docstrings individuelles qui posent problème, mais le problème est malheureusement beaucoup plus systémique que cela. En l'absence d'un emplacement centralisé pour trouver la documentation, cela nous conduira simplement à avoir de plus en plus de copies d'une documentation de plus en plus détaillée qui est répétée partout où chacun de ces types implicites est utilisé. Il sera donc particulièrement plus 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 à assembler lentement leur modèle mental de chaque type implicite en parcourant notre documentation en mode wiki, ou de manière fragmentaire à partir des exemples de StackOverflow, n'est pas non plus viable.

Définissez un objectif final

Idéalement, toute mention d'un type implicite doit renvoyer vers une seule page décrivant toutes les valeurs possibles de ce type, classées de la plus simple et la plus courante à la plus avancée ou ésotérique. Au lieu d'utiliser un espace visuel précieux dans la documentation de premier niveau de l'API pour énumérer au moindre fragment tous les types d'entrées possibles pour un paramètre particulier, nous pouvons ensuite utiliser ce même espace pour donner une description en mots simples de l'abstraction de traçage que le paramètre est censé contrôler.

Pour reprendre l'exemple de linestyle, voici ce que nous voulons dans la documentation LineCollection:

  1. Lien vers la documentation complète sur les entrées autorisées (combinaison de celles trouvées dans Line2D.set_linestyle et dans le tutoriel sur le style de ligne).
  2. Description en termes simples de ce que le paramètre est censé accomplir. Pour les utilisateurs expérimentés de matplotlib, cela se reflète clairement dans le nom du paramètre, mais ce n'est pas nécessairement le cas pour les nouveaux utilisateurs.

La façon dont cela ressemblerait dans la documentation LineCollection réelle est 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 de type LineStyle serait résolue par Sphinx pour pointer vers l'ensemble unique, primaire et complet de documentation sur la façon dont Matplotlib traite les styles de ligne.

Avantages

Cette approche comprend d'autres caractéristiques

  1. Donner toute l'étendue des possibilités de chaque fonction en texte brut (sans nécessiter de clics).
  2. Rendre l'option par défaut visible (sans aucun clic) L'affichage de l'option par défaut est souvent suffisant pour rafraîchir la mémoire des utilisateurs connus.
  3. Décrivez en détail les options ""les plus courantes"" et ""les plus simples"" d'un paramètre pour qu'elles soient facilement accessibles lors de la navigation (en un seul clic).
  4. Simplifiez le processus de découverte de fonctionnalités et de modes de saisie plus puissants en faisant défiler l'écran vers le bas pour afficher des options plus avancées (en un seul clic).
  5. Fournir une stratégie centralisée pour associer les documents ""API"" de premier niveau aux ""tutoriels" pertinents".
  6. Évitez l'explosion des documents API, car l'analyse des nombreuses options possibles pour chaque paramètre rend difficile la manipulation des docstrings individuelles.

Voici d'autres avantages de cette approche par rapport à la documentation actuelle:

  1. Les documents sont moins susceptibles d'être obsolètes en raison de la centralisation.
  2. Mise en forme canonique de nombreuses "normes implicites" de matplotlib (comme ce qu'est une "limites" au lieu d'une "étendue") qui doivent actuellement être apprises en lisant le code.
  3. Le processus met en évidence les problèmes de cohérence des API d'une manière qui peut être plus facilement suivie via l'outil de suivi des problèmes GitHub, ce qui contribue à améliorer notre API.
  4. Création de documents plus rapide 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 ""tutoriel"" centralisée par type implicite. Pour cela, vous devrez collaborer avec l'équipe de développement principale pour identifier une liste concrète des types implicites dont la documentation serait utile pour les utilisateurs (généralement, car ils contiennent des fonctionnalités cachées puissantes de notre bibliothèque, dont la documentation ne se trouve actuellement que dans des tutoriels difficiles à comprendre). Pour chaque type implicite, je vais ensuite synthétiser les différents tutoriels, documents d'API et pages d'exemple pertinents en une seule source de documentation faisant autorité, qui peut être liée à toute référence à ce type particulier.

Une fois que la documentation centralisée d'un type implicite donné est terminée, la deuxième tâche majeure commence: remplacer la documentation existante de l'API par des liens vers la nouvelle documentation, afin de simplifier au maximum l'utilisation de cette nouvelle documentation, à la fois pour ceux qui utilisent l'utilitaire help() intégré de Python et pour ceux qui consultent notre documentation en ligne.

Bien que le format exact de la documentation proposée ici soit susceptible d'être modifié à mesure que ce projet évolue, j'ai travaillé avec l'équipe principale de Matplotlib lors de ses "appels de développement" hebdomadaires afin d'établir un consensus selon lequel la stratégie proposée ici est l'approche la plus rapide, utile et techniquement maniable pour commencer à documenter ces types implicites (des notes sur ces appels md sont disponibles). J'utiliserai l'infrastructure"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 (à nouveau, en utilisant les documents 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 pourrions facilement modifier l'orthographe de ces références une fois que l'équipe de développement principale aura convenu de la meilleure stratégie à long terme pour intégrer notre nouvelle documentation "types" dans des classes Python authentiques, par exemple comme je l'ai proposé dans la proposition d'amélioration de Matplotlib 30.

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

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

Une version dynamique de ce document est disponible sur notre Discourse.