Fontes no Matplotlib #

O Matplotlib precisa de fontes para funcionar com seu mecanismo de texto, algumas das quais são fornecidas junto com a instalação. A fonte padrão é DejaVu Sans , que abrange a maioria dos sistemas de escrita europeus. No entanto, os usuários podem configurar as fontes padrão e fornecer suas próprias fontes personalizadas. Consulte Personalizando propriedades de texto para obter detalhes e Texto com glifos não latinos, em particular para glifos não suportados pelo DejaVu Sans.

O Matplotlib também fornece uma opção para descarregar a renderização de texto para um mecanismo TeX ( usetex=True), consulte Renderização de texto com LaTeX .

Fontes em PDF e PostScript #

As fontes têm uma história longa (e às vezes incompatível) na computação, levando a diferentes plataformas que suportam diferentes tipos de fontes. Na prática, existem 3 tipos de especificações de fonte que o Matplotlib suporta (além das 'fontes principais' em pdf que são explicadas mais adiante no guia):

Tipo de fonte #

Tipo 1 (PDF)

Tipo 3 (PDF/PS)

True Type (PDF)

Um dos tipos mais antigos, introduzido pela Adobe

Semelhante ao Tipo 1 em termos de introdução

Mais novos que os tipos anteriores, usados ​​comumente hoje, introduzidos pela Apple

Subconjunto restrito de PostScript, charstrings estão em bytecode

Linguagem PostScript completa, permite incorporar código arbitrário (em teoria, até renderizar fractais ao rasterizar!)

Inclua uma máquina virtual que possa executar código!

Essas fontes suportam dicas de fonte

Não suporta dicas de fontes

Sugestão suportada (máquina virtual processa as "dicas")

Não subconjunto através do Matplotlib

Subconjunto via módulo externo ttconv

Subconjunto via fonttools do módulo externo

OBSERVAÇÃO: a Adobe desativará o suporte para criação com fontes Tipo 1 em janeiro de 2023. Leia mais aqui.

Outras especificações de fonte que o Matplotlib suporta:

  • Fontes tipo 42 (PS):

  • Fontes OpenType:

    • OpenType é um novo padrão para fontes de tipo digital, desenvolvido em conjunto pela Adobe e pela Microsoft

    • Geralmente contém um conjunto de caracteres muito maior!

    • Suporte limitado com Matplotlib

Subconjunto de fonte #

Os formatos PDF e PostScript suportam a incorporação de fontes em arquivos, permitindo que o programa de exibição renderize corretamente o texto, independentemente de quais fontes estejam instaladas no computador do visualizador e sem a necessidade de pré-rasterizar o texto. Isso garante que, se a saída for ampliada ou redimensionada, o texto não ficará pixelado. No entanto, a incorporação de fontes completas no arquivo pode levar a arquivos de saída grandes, principalmente com fontes com muitos glifos, como aquelas que oferecem suporte a CJK (chinês/japonês/coreano).

A solução para esse problema é criar um subconjunto das fontes usadas no documento e incorporar apenas os glifos realmente usados. Isso obtém texto vetorial e tamanhos de arquivos pequenos. Calcular o subconjunto da fonte necessária e escrever a nova fonte (reduzida) são problemas complexos e, portanto, o Matplotlib depende do fontTools e de um fork fornecido do ttconv .

Atualmente, as fontes Type 3, Type 42 e TrueType são subconjuntos. Fontes tipo 1 não são.

Fontes principais #

Além da capacidade de incorporar fontes, como parte da especificação PostScript e PDF , há 14 fontes principais que os visualizadores compatíveis devem garantir que estejam disponíveis. Se você restringir seu documento apenas a essas fontes, não precisará incorporar nenhuma informação de fonte no documento, mas ainda obterá texto vetorial.

Isso é especialmente útil para gerar documentos realmente leves .:

# trigger core fonts for PDF backend
plt.rcParams["pdf.use14corefonts"] = True
# trigger core fonts for PS backend
plt.rcParams["ps.useafm"] = True

chars = "AFM ftw!"
fig, ax = plt.subplots()
ax.text(0.5, 0.5, chars)

fig.savefig("AFM_PDF.pdf", format="pdf")
fig.savefig("AFM_PS.ps", format="ps)

Fontes em SVG #

O texto pode ser enviado para SVG de duas maneiras controladas por rcParams["svg.fonttype"](padrão: 'path'):

  • como um caminho ( 'path') no SVG

  • como string no SVG com estilo de fonte no elemento ( 'none')

Ao salvar via 'path'Matplotlib, ele calculará o caminho dos glifos usados ​​como caminhos vetoriais e os gravará na saída. A vantagem disso é que o SVG terá a mesma aparência em todos os computadores, independentemente das fontes instaladas. No entanto, o texto não será editável após o fato. Em contraste, salvar com 'none'resultará em arquivos menores e o texto aparecerá diretamente na marcação. No entanto, a aparência pode variar com base no visualizador SVG e nas fontes disponíveis.

Fontes em Agg #

Para enviar texto para formatos raster via Agg, Matplotlib conta com FreeType . Como a renderização exata dos glifos muda entre as versões do FreeType, fixamos uma versão específica para nossos testes de comparação de imagens.

Como o Matplotlib seleciona fontes #

O uso interno de uma fonte no Matplotlib é um processo de três etapas:

  1. um FontPropertiesobjeto é criado (explícita ou implicitamente)

  2. com base no FontPropertiesobjeto, os métodos FontManagersão usados ​​para selecionar a "melhor" fonte mais próxima que o Matplotlib conhece (exceto para o 'none'modo SVG).

  3. o proxy Python para o objeto de fonte é usado pelo código de back-end para renderizar o texto - os detalhes exatos dependem do back-end via font_manager.get_font.

O algoritmo para selecionar a "melhor" fonte é uma versão modificada do algoritmo especificado pelas especificações CSS1 que é usado pelos navegadores da web. Este algoritmo leva em consideração o nome da família da fonte (por exemplo, "Arial", "Noto Sans CJK", "Hack", ...), o tamanho, estilo e peso. Além dos nomes de família que mapeiam diretamente para as fontes, existem cinco "nomes de família de fontes genéricas" (serif, monoespaçada, fantasia, cursiva e sem serifa) que serão mapeados internamente para qualquer um de um conjunto de fontes.

Atualmente, a API pública para executar a etapa 2 é FontManager.findfont(e esse método na FontManagerinstância global tem o alias no nível do módulo como font_manager.findfont), que encontrará apenas uma única fonte e retornará o caminho absoluto para a fonte no sistema de arquivos.

Fonte alternativa #

Não há fonte que cubra todo o espaço Unicode, portanto, é possível que os usuários exijam uma mistura de glifos que não podem ser satisfeitos com uma única fonte. Embora fosse possível usar várias fontes em uma Figura, em Textinstâncias distintas, não era possível usar várias fontes na mesma Textinstância (como faz um navegador da web). A partir do Matplotlib 3.6, os back-ends Agg, SVG, PDF e PS serão "substituídos" por meio de várias fontes em uma única Textinstância:

fig, ax = plt.subplots()
ax.text(
    .5, .5, "There are 几个汉字 in between!",
    family=['DejaVu Sans', 'WenQuanYi Zen Hei'],
    ha='center'
)

( Código fonte , png )

../../_images/fonts-1.png

A string "Existem 几个汉字 no meio!" renderizado com 2 fontes. #

Internamente, isso é implementado definindo a "família de fontes" em FontPropertiesobjetos para uma lista de famílias de fontes. Uma API privada (atualmente) extrai uma lista de caminhos para todas as fontes encontradas e, em seguida, constrói um único ft2font.FT2Fontobjeto que reconhece todas as fontes. Cada glifo da cadeia de caracteres é renderizado usando a primeira fonte na lista que contém esse glifo.

A maior parte desse trabalho foi feita por Aitik Gupta com o suporte do Google Summer of Code 2021.