Projeto Matplotlib

Esta página contém os detalhes de um projeto de redação 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:
Melhoria da descoberta 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 como enum. Além de imitar a API do Matlab, essas strings de parâmetros permitem que o usuário transmita valores semanticamente ricos como argumentos para funções matplotlib sem precisar importar explicitamente ou prefixar 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 pode ser uma string ou um matplotlib.path.Path. Embora isso seja verdade em muitos tipos implícitos, MarkerStyle é o único (que eu 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 teve que implementar suas 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 docstring docstring.interpd.update e o padrão de validação 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 "Validar em __init__").

Essas soluções funcionaram bem, mas a falta de um local explícito para documentar cada tipo implícito significa que a documentação costuma ser difícil de encontrar, grandes tabelas de valores permitidos são repetidas ao longo da documentação e, muitas vezes, uma declaração explícita do escopo de um tipo implícito está completamente ausente dos documentos. Veja os documentos plt.plot, por exemplo: em ""Notes", uma descrição do método de estilo de string de formato semelhante a Matlab menciona as opções linestyle, color e markers. Existem muito mais maneiras de transmitir esses três valores do que são sugeridos, mas, para muitos usuários, essa é a única fonte de compreensão sobre quais valores são possíveis para essas opções até se depararem com 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 se vincular a Line2D.set_linestyle (dois cliques necessários), onde as entradas possíveis são descritas, as entradas color e markers não fazem isso. 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 organizando as docstrings individuais que estão causando problemas, mas o problema, infelizmente, é muito mais sistêmico do que isso. Sem um local centralizado para encontrar a documentação, isso simplesmente nos levará a ter cada vez mais cópias de documentação cada vez mais detalhada repetida em todos os lugares em que cada um desses tipos implícitos seja usado, o que dificulta ainda mais que usuários iniciantes encontrem 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 de uma travessia de estilos de análise de wiki ao longo da nossa documentação ou parte de exemplos do StackOverflow, também não é sustentável.

Objetivo final

O ideal é que qualquer menção a um tipo implícito esteja vinculada a uma única página que descreve todos os valores possíveis que esse tipo pode assumir, 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 parcialmente 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 sobre qual abstração de plotagem o parâmetro deve controlar.

Para usar o exemplo de linestyle novamente, o que gostaríamos nos documentos de LineCollection seria apenas:

  1. Um link para os documentos completos das entradas permitidas (uma combinação das encontradas em Line2D.set_linestyle e no tutorial de linestyle).
  2. Uma descrição simples do que o parâmetro pretende realizar. Para usuários avançados da biblioteca matplotlib, isso é evidente no nome do parâmetro, mas para novos usuários, esse não precisa ser o caso.

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 em direção a um conjunto único, autoritativo e completo de documentação de como o Matplotlib trata estilos de linha.

Vantagens

Alguns recursos importantes dessa abordagem

  1. Tornar toda a capacidade de cada função óbvia em texto simples (sem a necessidade de cliques).
  2. Tornando a opção padrão visível (sem cliques). Ver a opção padrão geralmente é o suficiente para refrescar 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 facilmente disponíveis durante a navegação (com um único clique).
  4. Torne o processo de descoberta de recursos e métodos de entrada mais eficientes tão fácil quanto ""rolar para baixo" para conferir opções mais avançadas (com apenas um clique).
  5. Fornecer uma estratégia centralizada para vincular documentos de "API" de nível superior aos ""tutoriais" relevantes.
  6. Evite a explosão do documento de API, em que a verificação das muitas opções possíveis para cada parâmetro torna o docstrings individuais difícil de administrar.

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"" versus uma ""extensão"") 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 possa ser rastreada mais facilmente pelo rastreador de problemas do GitHub, ajudando no processo de melhoria da nossa API.
  4. Tempos de compilação de documentos mais rápidos, devido a reduções significativas na quantidade de texto que precisa ser analisada.

Implementação

As melhorias descritas acima vão exigir dois esforços importantes. Um redator técnico dedicado será inestimável. A primeira é criar uma página "tutorial" centralizada por tipo implícito. Isso exigirá 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 porque eles contêm recursos avançados e ocultos da nossa biblioteca cuja documentação só é encontrada atualmente em tutoriais difíceis de encontrar. Para cada tipo implícito, sintetizarei os vários tutoriais, documentos de API e páginas de exemplo relevantes 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 é concluída, começa o segundo grande esforço: substituir a documentação da API atual 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 procuram 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 da 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 md). Vou usar a infraestrutura ""tutoriais" existente para os estágios iniciais de criação da documentação centralizada para cada tipo implícito, permitindo fazer referência fácil a 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`.
""""""

Daqui para frente, poderíamos facilmente mudar a forma como essas referências são escritas quando a equipe principal de desenvolvedores define a melhor estratégia de longo prazo para incorporar nossa nova documentação "tipos" em classes Python legítimas, por exemplo, conforme proposto na Proposta de melhoria do Matplotlib 30.

Por fim, a lista preliminar de tipos implícitos que proponho documentar durante a temporada de Documentos 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.