Proyecto matplotlib

En esta página, se incluyen los detalles de un proyecto de redacción técnica aceptado para la temporada de Documentos de Google.

Resumen del proyecto

Organización de código abierto:
Matplotlib
Redactor técnico:
brunobeltran
Nombre del proyecto:
Mejora la visibilidad de las funciones estandarizando la documentación de los tipos “implícitos”.
Duración del proyecto:
Larga duración (5 meses)

Project description

Motivación

Históricamente, la API de matplotlib se basó en gran medida en ""tipos implícitos"" de cadena como enum. Además de imitar la API de matlab, estas cadenas de parámetros permiten al usuario pasar valores ricos en semántica como argumentos a las funciones de matplotlib sin tener que importar explícitamente o anteponer de forma verbosa un valor de enumeración real solo para pasar opciones de trama básicas (es decir, plt.plot(x, y, linestyle='solid') es más fácil de escribir y menos redundante que algo como plt.plot(x, y, linestyle=mpl.LineStyle.solid)).

Muchos de estos tipos implícitos de cadena como enumeración evolucionaron a funciones más sofisticadas. Por ejemplo, un linestyle ahora puede ser una cadena o un tupla de 2 secuencias, y un MarkerStyle ahora puede ser una cadena o un matplotlib.path.Path. Si bien esto es cierto para muchos tipos implícitos, MarkerStyle es el único (que yo sepa) que tiene el estado de haberse actualizado a una clase de Python adecuada.

Debido a que estos tipos implícitos no son clases en sí, Matplotlib históricamente tuvo que implementar sus propias soluciones para centralizar la documentación y la validación de estos tipos implícitos (p.ej., el patrón de interpolación de docstring docstring.interpd.update y el patrón de validador cbook._check_in_list, respectivamente) en lugar de usar los conjuntos de herramientas estándar que proporcionan las clases de Python (p.ej., docstrings y el patrón validate-at-__init__, respectivamente).

Si bien estas soluciones funcionaron bien para nosotros, la falta de una ubicación explícita para documentar cada tipo implícito significa que, a menudo, es difícil encontrar la documentación, se repiten grandes tablas de valores permitidos en toda la documentación y, a menudo, falta por completo una declaración explícita del alcance de un tipo implícito en los documentos. Por ejemplo, en los documentos de plt.plot, en las ""Notas"", una descripción del método de diseño de cadenas de formato similar a Matlab menciona las opciones linestyle, color y markers. Existen muchas más formas de pasar estos tres valores de las que se insinúan, pero para muchos usuarios, esta es su única fuente de información sobre los valores posibles para esas opciones hasta que encuentran uno de los instructivos relevantes. Se incluye una tabla de atributos Line2D para mostrarle al lector las opciones que tiene para controlar su trama. Sin embargo, si bien la entrada linestyle hace un buen trabajo para vincular a Line2D.set_linestyle (se requieren dos clics) donde se describen las entradas posibles, las entradas color y markers no lo hacen. color simplemente se vincula a Line2D.set_color, que no ofrece ninguna intuición sobre qué tipos de entradas se permiten.

Se podría argumentar que esto es algo que se puede solucionar simplemente ordenando las docstrings individuales que causan problemas, pero, lamentablemente, el problema es mucho más sistémico que eso. Sin un lugar centralizado para encontrar la documentación, esto solo hará que tengamos cada vez más copias de documentación cada vez más detallada que se repite en todas partes donde se usa cada uno de estos tipos implícitos, lo que dificulta aún más que los usuarios principiantes encuentren el parámetro que necesitan. Sin embargo, el sistema actual, que obliga a los usuarios a armar lentamente su modelo mental de cada tipo implícito a través de un recorrido de estilo de wiki en toda nuestra documentación o de forma fragmentada a partir de ejemplos de StackOverflow, tampoco es sostenible.

Objetivo final

Lo ideal es que cualquier mención de un tipo implícito vincule a una sola página que describa todos los valores posibles que puede tomar ese tipo, ordenados de los más simples y comunes a los más avanzados o esotéricos. En lugar de usar un espacio visual valioso en la documentación de la API de nivel superior con el objetivo de enumerar por partes todos los tipos de entrada posibles para un parámetro en particular, podemos usar ese mismo espacio para brindar una descripción clara de lo que la abstracción graficar debe controlar el parámetro.

Para volver a usar el ejemplo de linestyle, lo que queremos en los documentos LineCollection es solo lo siguiente:

  1. Un vínculo para completar la documentación de las entradas permitidas (una combinación de las que se encuentran en Line2D.set_linestyle y el instructivo de linestyle).
  2. Una descripción en palabras simples de lo que se espera que logre el parámetro. Para los usuarios avanzados de matplotlib, esto es evidente en el nombre del parámetro, pero para los usuarios nuevos no tiene por qué ser así.

La forma en que se vería esto en la documentación real de LineCollection es solo 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. """""", en la que Sphinx resolvería la referencia de tipo LineStyle para dirigir a un conjunto único, autorizado y completo de documentación sobre cómo Matplotlib trata los estilos de línea.

Beneficios

Estas son algunas de las funciones potentes de este enfoque:

  1. Hacer que la totalidad de lo que cada función puede hacer sea evidente en texto sin formato (sin necesidad de hacer clic).
  2. Hacer que la opción predeterminada sea visible (sin clics) A menudo, ver la opción predeterminada es suficiente para recordar a los usuarios recurrentes.
  3. Haz una descripción completa de las opciones ""más comunes"" y ""más fáciles"" para un parámetro que esté fácilmente disponible durante la navegación (con un solo clic).
  4. Haz que el proceso de descubrir funciones y métodos de entrada más potentes sea tan fácil como ""desplazarse hacia abajo"" para ver opciones más avanzadas (con un solo clic).
  5. Proporciona una estrategia centralizada para vincular la documentación de ""API"" de nivel superior a los ""instructivos"" relevantes.
  6. Evita la explosión de documentos de API, ya que la búsqueda de muchas opciones posibles para cada parámetro hace que las docstrings individuales sean difíciles de manejar.

Estos son otros beneficios de este enfoque en comparación con los documentos actuales:

  1. Es menos probable que los documentos queden obsoletos debido a la centralización.
  2. Canonización de muchos de los ""estándares implícitos"" de matplotlib (como lo que es un ""límite"" en comparación con un ""alcance"") que actualmente se deben aprender leyendo el código.
  3. El proceso destacaría los problemas de la coherencia de la API de una manera que se pudiera rastrear más fácilmente a través de la Herramienta de seguimiento de errores de GitHub, lo que ayudaría con el proceso de mejorar nuestra API.
  4. Tiempos de compilación de documentos más rápidos, debido a disminuciones significativas en la cantidad de texto que se debe analizar

Implementación

Las mejoras descritas anteriormente requerirán dos esfuerzos importantes para los que un escritor técnico dedicado será invaluable. El primero es crear una página de "instructivo" centralizada por tipo implícito. Esto requerirá trabajar con el equipo principal de desarrolladores para identificar una lista concreta de tipos implícitos cuya documentación sería valiosa para los usuarios (por lo general, porque contienen funciones ocultas y potentes de nuestra biblioteca cuya documentación actualmente solo se encuentra en instructivos difíciles de encontrar). Para cada tipo implícito, sintetizaré los diversos instructivos relevantes, documentos de APIs y páginas de ejemplo en una sola fuente autorizada de documentación que se puede vincular a cualquier lugar al que se haga referencia a ese tipo en particular.

Una vez que se completa la documentación centralizada para un tipo implícito determinado, comienza el segundo esfuerzo importante: reemplazar la documentación existente de la API por vínculos a la nueva documentación, con el objetivo de que la experiencia de usar esta nueva documentación sea lo más fácil posible, tanto para quienes usan la utilidad help() integrada de Python como para quienes exploran nuestra documentación en línea.

Si bien el formato exacto de la documentación propuesta aquí está sujeto a cambios a medida que evoluciona este proyecto, trabajé con el equipo principal de Matplotlib durante sus “llamadas para desarrolladores” semanales para establecer un consenso de que la estrategia propuesta aquí es el enfoque más expeditivo, útil y técnicamente manejable para comenzar a documentar estos “tipos implícitos” (hay notas sobre estas llamadas). Se encuentran disponibles las notas sobre estos hackeos. Usaré la infraestructura existente de ""instructivos"" para las etapas iniciales de la creación de la documentación centralizada para cada tipo implícito, lo que me permitirá hacer referencia a estas páginas de la siguiente manera, sin tener que crear clases públicas nuevas (una vez más, usando la documentación de LineCollection como ejemplo):

""""""
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`.
""""""

En el futuro, podríamos cambiar fácilmente la forma en que se escriben estas referencias una vez que el equipo principal de desarrolladores esté de acuerdo con la mejor estrategia a largo plazo para incorporar nuestra nueva documentación de ""tipos"" en clases de Python genuinas, por ejemplo, como lo propuse en la Propuesta de mejora 30 de Matplotlib.

Por último, la lista preliminar de tipos implícitos que propongo documentar durante esta temporada de Documentos de Google es la siguiente:

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

Puedes encontrar una versión actualizada de este documento en nuestro canal de Discourse.