Proyecto matplotlib

Esta página contiene 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
Escritor técnico:
brunobeltrán
Nombre del proyecto:
Mejora la visibilidad de las funciones mediante la estandarización de la documentación de 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 strings como enumeración. Además de imitar la API de matlab, estas strings de parámetros permiten al usuario pasar valores con muchos recursos semánticos como argumentos a las funciones de matplotlib sin tener que importar explícitamente o prefijar de forma detallada un valor de enumeración real solo para pasar opciones básicas de trazado (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)).

Desde entonces, muchos de estos tipos implícitos de string como enumeración evolucionaron funciones más sofisticadas. Por ejemplo, un objeto linestyle ahora puede ser una cadena o una tupla de 2 secuencias, y un elemento MarkerStyle ahora puede ser una cadena o una matplotlib.path.Path. Si bien esto se aplica a muchos tipos implícitos, (según mi conocimiento) MarkerStyle es el único que tiene el estado de actualizarse a una clase de Python adecuada.

Debido a que estos tipos implícitos no son clases en sí mismos, Matplotlib históricamente tuvo que lanzar 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 de docstring.interpd.update y el patrón del validador de cbook._check_in_list, respectivamente), en lugar de usar las cadenas de herramientas estándar que proporcionan las clases Python (p.ej., docstrings y el patrón de validación en __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 la documentación suele ser difícil de encontrar, tablas grandes de valores permitidos se repiten 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 "Notes", una descripción del método de estilo format-string de matlab menciona las opciones linestyle, color y markers. Hay muchas más formas de pasar estos tres valores de las que se sugieren, pero para muchos usuarios, esta es su única fuente de información sobre qué valores son posibles para esas opciones hasta que encuentran uno de los instructivos relevantes. Se incluye una tabla de atributos Line2D para intentar mostrarle al lector las opciones que tiene para controlar su diagrama. Sin embargo, aunque la entrada linestyle se vincula con 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 los tipos de entradas que se permiten.

Se podría decir que esto es algo que se puede solucionar simplemente ordenando las docstrings individuales que causan problemas, pero desafortunadamente el problema es mucho más sistémico que eso. Sin un lugar centralizado para encontrar la documentación, esto simplemente hará que tengamos cada vez más copias de la documentación cada vez más detallada que se repitan en todos los lugares donde se use cada uno de estos tipos implícitos, lo que hará que resulte especialmente difícil para los usuarios principiantes encontrar el parámetro que necesitan. Sin embargo, el sistema actual, que obliga a los usuarios a unir lentamente su modelo mental de cada tipo implícito a través del recorrido de estilo de wiki-Diving en toda nuestra documentación, o por fragmentos de los ejemplos de StackOverflow, tampoco es sustentable.

Finalizar objetivo

Lo ideal es que cualquier mención de un tipo implícito se vincule a una sola página que describa todos los valores posibles que puede tomar ese tipo, ordenados desde los más simples y comunes hasta 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 para 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 de palabra sencilla de la abstracción del trazado que 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 los documentos de las entradas permitidas (una combinación de las que se encuentran en Line2D.set_linestyle y el instructivo de estilo de línea).
  2. Es una descripción con palabras simples del objetivo del parámetro. Para los usuarios avanzados de matplotlib, esto es evidente a partir del nombre del parámetro, pero para los usuarios nuevos este no tiene que ser el caso.

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

Beneficios

Algunas funciones poderosas de este enfoque incluyen

  1. Hacer que el alcance completo de cada función sea evidente en texto sin formato (sin necesidad de clics).
  2. Hacer visible la opción predeterminada (sin clics). Ver la opción predeterminada es suficiente para refrescar la memoria de los usuarios recurrentes.
  3. Realiza una descripción completa de las opciones "más comunes" y "más fáciles" para un parámetro que esté fácilmente disponible cuando se navegue (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 solo un clic).
  5. Ofrece una estrategia centralizada para vincular los documentos de “API” de nivel superior con los “instructivos” relevantes.
  6. Evita la explosión de documentos de API, en el que el escaneo de muchas opciones posibles de cada parámetro hace que las docstrings individuales sean difíciles de manejar.

Otros beneficios de este enfoque en comparación con los documentos actuales son los siguientes:

  1. Es menos probable que los documentos se vuelvan obsoletos debido a la centralización.
  2. La canonicalización de muchos de los ""estándares implícitos" de matplotlib (como lo que es un ""límites" en comparación con una "extensión") que actualmente se deben aprender mediante la lectura del código.
  3. El proceso destacaría los problemas de coherencia de la API de una manera que se pueda rastrear más fácilmente mediante la herramienta de seguimiento de problemas de GitHub, lo que ayudaría con el proceso de mejora de nuestra API.
  4. Menor tiempo de compilación de documentos debido a disminuciones significativas en la cantidad de texto que debe analizarse

Implementación

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

Una vez que se completa la documentación centralizada de un tipo implícito determinado, comienza el segundo esfuerzo importante: reemplazar la documentación de la API existente con vínculos a la documentación nueva, con el objetivo de facilitar al máximo la experiencia de usar esta nueva documentación, tanto para los usuarios de la utilidad help() integrada de Python como para los que 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 de desarrollo” semanales para establecer un consenso de que la estrategia propuesta aquí es el enfoque más conveniente, útil y técnicamente manejable para comenzar a documentar estos “tipos implícitos” (las notas sobre estas llamadas están disponibles en). Usaré la infraestructura de "instructivos" existente para las etapas iniciales de creación de la documentación centralizada para cada tipo implícito, lo que me permite hacer referencia con facilidad a estas páginas de la siguiente manera, sin tener que crear ninguna clase pública nueva (una vez más, con los documentos 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`.
""""""

De ahora en adelante, podríamos cambiar fácilmente la forma en que se escriben estas referencias una vez que el equipo principal de desarrolladores acuerde cuál es la mejor estrategia a largo plazo para incorporar nuestra nueva documentación de ""tipos" a las clases de Python de buena fe, por ejemplo, según lo que propongo en la Propuesta de mejoras de Matplotlib 30.

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 viva de este documento en nuestro Discourse.