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éliorer la visibilité des caractéristiques en standardisant la documentation des types "implicites"
Durée du projet:
Exécution longue (5 mois)

Project description

Motivation

Historiquement, l'API de matplotlib s'appuyait fortement 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 explicitement ou à ajouter un préfixe détaillé à une valeur d'énumération réelle pour transmettre des 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 type 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 le statut d'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 toujours dû déployer ses propres solutions pour centraliser la documentation et la validation de ces types implicites (par exemple, le modèle d'interpolation de 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 chaînes de document 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'une instruction explicite concernant le champ d'application d'un type implicite est souvent absente de la documentation. Prenons l'exemple de la documentation plt.plot. Dans "Notes", une description de la méthode de style chaîne de mise en forme 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, c'est 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 tenter de montrer au lecteur les options dont il dispose pour contrôler son tracé. Toutefois, bien que l'entrée linestyle soit correctement liée à 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 soutenir 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. Sans emplacement centralisé pour trouver la documentation, cela nous conduira simplement à avoir de plus en plus de copies de documents de plus en plus détaillés partout où chacun de ces types implicites est utilisé. Il sera donc 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 à assembler lentement leur modèle mental de chaque type implicite via un balayage de style wiki dans notre documentation, ou de manière fragmentaire à partir d'exemples 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 par blocs 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 quelques mots de l'abstraction de traçage que le paramètre est censé contrôler.

Pour reprendre l'exemple de linestyle, ce que nous voudrions dans la LineCollection documentation est simplement:

  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 est évident à partir du nom du paramètre, mais ce n'est pas nécessairement le cas pour les nouveaux utilisateurs.

La façon dont cela apparaîtrait dans les documents LineCollection réels 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 un ensemble unique, primaire et complet de documentation sur la façon dont Matplotlib traite les styles de ligne.

Avantages

Cette approche présente plusieurs caractéristiques majeures, parmi lesquelles

  1. Mettre en évidence toute l'étendue des possibilités de chaque fonction en texte brut (sans nécessiter de clic)
  2. Affichage de l'option par défaut (sans aucun clic) L'affichage de l'option par défaut est souvent suffisant pour se rafraîchir la mémoire des utilisateurs connus.
  3. Décrivez en détail les options "la plus courante" et "la plus facile" d'un paramètre pour qu'elles soient facilement accessibles lors de la navigation (d'un simple clic).
  4. Simplifiez la découverte de fonctionnalités et de méthodes de saisie plus puissantes 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 d'API, où l'analyse des nombreuses options possibles pour chaque paramètre rend difficile la gestion des docstrings individuelles.

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

  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 qui est un ""limites" par rapport à 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. Vous devrez travailler avec l'équipe de développeurs principale pour identifier une liste concrète de types implicites dont la documentation pourrait intéresser les utilisateurs (généralement, car elles 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 vais ensuite synthétiser les différents tutoriels, documents d'API et pages d'exemples pertinents en une seule source de documentation faisant autorité, qui peut être liée à toutes les références à 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, dans l'optique de simplifier au maximum l'utilisation de cette nouvelle documentation, tant pour les utilisateurs de l'utilitaire help() intégré de Python que pour ceux qui consultent notre documentation en ligne.

Le format exact de la documentation proposée ici est susceptible d'être modifié à mesure que ce projet évolue, mais j'ai travaillé avec l'équipe principale de Matplotlib lors des "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 maniable pour commencer à documenter ces types de piratage implicites (des notes sont disponibles pour ces appels). J'utiliserai l'infrastructure "tutoriels" existante pour les étapes initiales de 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 d'autres classes publiques (encore une fois, 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éveloppeurs principale se sera d'accord sur la meilleure stratégie à long terme pour intégrer notre nouvelle documentation sur les "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 pendant 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.