Projeto Matplotlib

Esta página contém os detalhes de um projeto de escrita técnica aceito para a temporada de documentos do Google.

Resumo do projeto

Organização de código aberto:
Matplotlib
(em inglês)
Redator técnico:
brunobeltran
Nome do projeto:
Como melhorar a detecção de recursos com a padronização da documentação de tipos "implícitos"
Duração do projeto:
De longa duração (5 meses)

Project description

Motivação

Historicamente, a API da matplotlib depende muito de ““tipos implícitos” de string-as-enum. Além de imitar a API do Matlab, essas strings de parâmetros permitem que o usuário transmita valores semanticamente ricos em argumentos para funções matplotlib sem precisar importar ou prefixar explicitamente um valor de enumeração real apenas para passar opções básicas de plotagem (por exemplo, plt.plot(x, y, linestyle='solid') é mais fácil de digitar e menos redundante do que algo como plt.plot(x, y, linestyle=mpl.LineStyle.solid)).

Desde então, muitos desses tipos implícitos de string como enum evoluíram recursos mais sofisticados. Por exemplo, um linestyle agora pode ser uma string ou duas tuplas de sequências, e um MarkerStyle agora pode ser uma string ou um matplotlib.path.Path. Embora isso seja verdade para muitos tipos implícitos, MarkerStyle é o único (que sei) que tem o status de upgrade para uma classe Python adequada.

Como esses tipos implícitos não são classes em si, o Matplotlib teve historicamente que implementar as próprias soluções para centralizar a documentação e a validação desses tipos implícitos (por exemplo, o padrão de interpolação de docstring docstring.interpd.update e o padrão de validador cbook._check_in_list, respectivamente) em vez de usar os conjuntos de ferramentas padrão fornecidos pelas classes Python (por exemplo, docstrings e o padrão validate-em-__init__, respectivamente).

Essas soluções funcionaram bem para nós, mas a falta de um local explícito para documentar cada tipo implícito significa que a documentação geralmente é difícil de encontrar, grandes tabelas de valores permitidos são repetidas por toda a documentação e, muitas vezes, uma declaração explícita do escopo de um tipo implícito está completamente ausente dos documentos. Considere os documentos plt.plot, por exemplo: em "Notes", uma descrição do método de estilo de string de formato do matlab menciona as opções linestyle, color e markers. Existem muitas outras maneiras de transmitir esses três valores do que as sugeridas, mas, para muitos usuários, essa é a única fonte de compreensão sobre quais valores são possíveis para essas opções até encontrar um dos tutoriais relevantes. Uma tabela de atributos Line2D é incluída em uma tentativa de mostrar ao leitor quais opções ele tem para controlar o gráfico. No entanto, embora a entrada linestyle faça um bom trabalho ao vincular a Line2D.set_linestyle (dois cliques necessários) em que as entradas possíveis são descritas, as entradas color e markers não fazem isso. O color simplesmente se vincula a Line2D.set_color, o que não oferece nenhuma intuição sobre quais tipos de entradas são permitidos.

É possível argumentar que isso é algo que pode ser corrigido simplesmente ordenando as docstrings individuais que estão causando problemas, mas, infelizmente, o problema é muito mais sistêmico do que isso. Sem um local centralizado para encontrar a documentação, isso apenas nos levará a ter mais e mais cópias de documentação cada vez mais detalhada repetida em todos os lugares em que cada um desses tipos implícitos for usado, tornando mais difícil para os usuários iniciantes simplesmente encontrarem o parâmetro de que precisam. No entanto, o sistema atual, que força os usuários a reunir lentamente o modelo mental de cada tipo implícito por meio da travessia de estilos de análise de wiki ao longo da nossa documentação ou partes de exemplos do StackOverflow, também não é sustentável.

Objetivo final

O ideal é que qualquer menção de um tipo implícito tenha um link para uma única página que descreve todos os valores possíveis que o tipo pode receber, ordenados do mais simples e comum ao mais avançado ou esotérico. Em vez de usar um espaço visual valioso na documentação da API de nível superior para enumerar em partes todos os tipos de entrada possíveis para um parâmetro específico, podemos usar esse mesmo espaço para fornecer uma descrição simples da abstração de plotagem que o parâmetro deve controlar.

Para usar o exemplo de linestyle novamente, o que queremos nos documentos LineCollection é:

  1. Um link para os documentos completos das entradas permitidas (uma combinação daquelas encontradas em Line2D.set_linestyle e no tutorial de estilo de linha).
  2. Uma descrição simples do que o parâmetro deve realizar. Para usuários avançados de matplotlib, isso é evidente no nome do parâmetro, mas não é necessário para novos usuários.

A forma como isso ficaria nos documentos LineCollection reais é apenas 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. """""", em que a referência de tipo LineStyle seria resolvida pelo Sphinx para apontar para um conjunto único, autoritativo e completo de documentação sobre como o Matplotlib trata estilos de linha.

Vantagens

Alguns recursos poderosos dessa abordagem incluem

  1. Deixar claro o que cada função é capaz de fazer em texto simples (sem a necessidade de cliques).
  2. Tornando a opção padrão visível (com zero cliques). Ver a opção padrão geralmente é suficiente para fazer a memória dos usuários recorrentes.
  3. Faça uma descrição completa das opções "mais comuns" e "mais fáceis" para um parâmetro de fácil acesso durante a navegação (com um único clique).
  4. Facilite o processo de descoberta de recursos e métodos de entrada mais avançados, como "rolar para baixo" para conferir opções mais avançadas (com apenas um clique).
  5. Fornecer uma estratégia centralizada para vincular documentos "API" de nível superior aos "tutoriais" relevantes.
  6. Evite a explosão do documento de API, em que verificar as muitas opções possíveis para cada parâmetro torna docstrings individuais difíceis de gerenciar.

Outros benefícios dessa abordagem em relação aos documentos atuais são:

  1. Os documentos têm menos probabilidade de ficarem desatualizados devido à centralização.
  2. Canonização de muitos dos ""padrões implícitos"" de matplotlib (como o que é um ""limites"" em comparação com uma ""extensões") que atualmente precisam ser aprendidos com a leitura do código.
  3. O processo destacaria problemas com a consistência da API de uma maneira que podesse ser rastreada mais facilmente pelo Issue Tracker do GitHub, ajudando no processo de melhoria da nossa API.
  4. Tempos de compilação de documentos mais rápidos, devido a diminuições significativas na quantidade de texto que precisa ser analisado.

Implementação

Para realizar as melhorias descritas acima, é preciso ter dois esforços importantes. Por isso, um redator técnico dedicado será inestimável. A primeira é criar uma página "tutorial" centralizada por tipo implícito. Isso exigirá um trabalho com a equipe de desenvolvimento principal para identificar uma lista concreta de tipos implícitos, cuja documentação seja valiosa para os usuários, geralmente por conter recursos poderosos e ocultos da nossa biblioteca, cuja documentação se encontra atualmente apenas em tutoriais difíceis de encontrar. Para cada tipo implícito, vou sintetizar os vários tutoriais relevantes, documentos de API e páginas de exemplo em uma única fonte autoritativa de documentação que pode ser vinculada a qualquer lugar em que esse tipo específico seja referenciado.

Depois que a documentação centralizada para um determinado tipo implícito for concluída, começa o segundo grande esforço: substituir a documentação da API existente por links para a nova documentação, com o objetivo de facilitar ao máximo a experiência de uso dessa nova documentação, tanto para aqueles que usam o utilitário help() integrado do Python quanto para aqueles que navegam pela nossa documentação on-line.

Embora o formato exato da documentação proposta aqui esteja sujeito a mudanças à medida que o projeto evolui, trabalhei com a equipe principal do Matplotlib durante as "chamadas de desenvolvimento" semanais para estabelecer um consenso de que a estratégia proposta aqui é a abordagem mais conveniente, útil e tecnicamente tratável para começar a documentar esses ""tipos implícitos" (observações sobre essas chamadas). Vou usar a infraestrutura "tutoriais" atual para os estágios iniciais de criação da documentação centralizada para cada tipo implícito, permitindo que eu mencione facilmente essas páginas da seguinte maneira, sem precisar criar novas classes públicas (novamente, usando os documentos LineCollection como exemplo):

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

Futuramente, poderemos mudar facilmente a forma como essas referências são escritas quando a equipe de desenvolvimento principal chegar a um acordo sobre a melhor estratégia de longo prazo para incorporar nossa nova documentação "tipos" em classes Python legítimas, por exemplo, conforme minha proposta na Proposta de melhoria do Matplotlib 30.

Por fim, a lista preliminar de tipos implícitos que proponho documentar durante esta temporada de documentos do Google é:

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

Uma versão ativa deste documento está disponível no nosso Discurso.