Fuentes en Matplotlib #
Matplotlib necesita fuentes para funcionar con su motor de texto, algunas de las cuales se envían junto con la instalación. La fuente predeterminada es DejaVu Sans , que cubre la mayoría de los sistemas de escritura europeos. Sin embargo, los usuarios pueden configurar las fuentes predeterminadas y proporcionar sus propias fuentes personalizadas. Consulte Personalización de propiedades de texto para obtener detalles y Texto con glifos no latinos en particular para glifos no admitidos por DejaVu Sans.
Matplotlib también ofrece una opción para descargar la representación de texto en un motor TeX ( usetex=True
), consulte Representación de texto con LaTeX .
Fuentes en PDF y PostScript #
Las fuentes tienen una historia larga (ya veces incompatible) en la informática, lo que lleva a diferentes plataformas que admiten diferentes tipos de fuentes. En la práctica, hay 3 tipos de especificaciones de fuente compatibles con Matplotlib (además de las 'fuentes principales' en pdf que se explican más adelante en la guía):
Tipo 1 (PDF) |
Tipo 3 (PDF/PS) |
Tipo verdadero (PDF) |
---|---|---|
Uno de los tipos más antiguos, introducido por Adobe |
Similar al Tipo 1 en términos de introducción |
Más nuevos que los tipos anteriores, utilizados comúnmente en la actualidad, presentados por Apple |
Subconjunto restringido de PostScript, las cadenas de caracteres están en código de bytes |
Lenguaje PostScript completo, permite incrustar código arbitrario (en teoría, ¡incluso renderizar fractales al rasterizar!) |
¡Incluya una máquina virtual que pueda ejecutar código! |
Estas fuentes admiten sugerencias de fuentes |
No admite sugerencias de fuentes |
Sugerencias admitidas (la máquina virtual procesa las "sugerencias") |
Sin subconjuntos a través de Matplotlib |
Subdividido a través del módulo externo ttconv |
Subdividido a través de fonttools de módulos externos |
NOTA: Adobe desactivará la compatibilidad con la creación con fuentes Tipo 1 en enero de 2023. Lea más aquí.
Otras especificaciones de fuentes compatibles con Matplotlib:
Escriba 42 fuentes (PS):
Envoltorio PostScript alrededor de las fuentes TrueType
¡ 42 es la respuesta a la vida, el universo y todo!
Matplotlib usa una biblioteca externa llamada fonttools para crear subconjuntos de estos tipos de fuentes
Fuentes OpenType:
OpenType es un nuevo estándar para fuentes tipográficas digitales, desarrollado conjuntamente por Adobe y Microsoft
¡Generalmente contienen un conjunto de caracteres mucho más grande!
Soporte limitado con Matplotlib
Subconjunto de fuentes #
Los formatos PDF y PostScript admiten la incrustación de fuentes en los archivos, lo que permite que el programa de visualización represente correctamente el texto, independientemente de las fuentes instaladas en la computadora del espectador y sin necesidad de pretrasterizar el texto. Esto asegura que si la salida se amplía o cambia de tamaño, el texto no se pixela. Sin embargo, incrustar fuentes completas en el archivo puede generar archivos de salida de gran tamaño, especialmente con fuentes con muchos glifos, como las que admiten CJK (chino/japonés/coreano).
La solución a este problema es crear un subconjunto de las fuentes utilizadas en el documento e incrustar solo los glifos realmente utilizados. Esto obtiene tanto texto vectorial como archivos de tamaño pequeño. Calcular el subconjunto de la fuente requerida y escribir la fuente nueva (reducida) son problemas complejos y, por lo tanto, Matplotlib se basa en fontTools y una bifurcación de ttconv .
Actualmente, las fuentes Type 3, Type 42 y TrueType están subdivididas. Las fuentes tipo 1 no lo son.
Fuentes principales #
Además de la capacidad de incrustar fuentes, como parte de las especificaciones de PostScript y PDF, hay 14 fuentes principales que los espectadores que cumplan con las normas deben asegurarse de que estén disponibles. Si restringe su documento a solo estas fuentes, no tiene que incrustar ninguna información de fuente en el documento pero aún así obtener texto vectorial.
Esto es especialmente útil para generar documentos realmente livianos :
# 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)
Fuentes en SVG #
El texto puede enviarse a SVG de dos formas controladas por rcParams["svg.fonttype"]
(predeterminado: 'path'
):
como ruta (
'path'
) en el SVGcomo cadena en el SVG con estilo de fuente en el elemento (
'none'
)
Al guardar a través de 'path'
Matplotlib, calculará la ruta de los glifos utilizados como rutas vectoriales y las escribirá en la salida. La ventaja de esto es que el SVG se verá igual en todas las computadoras, independientemente de las fuentes que estén instaladas. Sin embargo, el texto no será editable después del hecho. Por el contrario, guardar con 'none'
dará como resultado archivos más pequeños y el texto aparecerá directamente en el marcado. Sin embargo, la apariencia puede variar según el visor SVG y las fuentes disponibles.
Fuentes en Agg #
Para generar texto en formatos de trama a través de Agg, Matplotlib se basa en FreeType . Debido a que la representación exacta de los glifos cambia entre las versiones de FreeType, fijamos una versión específica para nuestras pruebas de comparación de imágenes.
Cómo selecciona Matplotlib las fuentes #
El uso interno de una fuente en Matplotlib es un proceso de tres pasos:
se crea un
FontProperties
objeto (explícita o implícitamente)según el
FontProperties
objeto, los métodosFontManager
se utilizan para seleccionar la "mejor" fuente más cercana que Matplotlib conoce (excepto el'none'
modo de SVG).el proxy de Python para el objeto de fuente es utilizado por el código de backend para representar el texto; los detalles exactos dependen del backend a través de
font_manager.get_font
.
El algoritmo para seleccionar la "mejor" fuente es una versión modificada del algoritmo especificado por las Especificaciones CSS1 que utilizan los navegadores web. Este algoritmo tiene en cuenta el nombre de la familia de fuentes (por ejemplo, "Arial", "Noto Sans CJK", "Hack", ...), el tamaño, el estilo y el peso. Además de los nombres de familias que se asignan directamente a las fuentes, hay cinco "nombres de familias de fuentes genéricas" (serif, monoespaciado, fantasía, cursiva y sans-serif) que se asignarán internamente a cualquiera de un conjunto de fuentes.
Actualmente, la API pública para realizar el paso 2 es FontManager.findfont
(y ese método en la FontManager
instancia global tiene un alias en el nivel del módulo como
font_manager.findfont
), que solo encontrará una sola fuente y devolverá la ruta absoluta a la fuente en el sistema de archivos.
Número de reserva de fuente
No hay una fuente que cubra todo el espacio Unicode, por lo que es posible que los usuarios requieran una combinación de glifos que no se pueden satisfacer con una sola fuente. Si bien ha sido posible usar varias fuentes dentro de una figura, en distintas
Text
instancias, antes no era posible usar varias fuentes en la misma Text
instancia (como lo hace un navegador web). A partir de Matplotlib 3.6, los backends Agg, SVG, PDF y PS "retrocederán" a través de múltiples fuentes en una sola
Text
instancia:
fig, ax = plt.subplots()
ax.text(
.5, .5, "There are 几个汉字 in between!",
family=['DejaVu Sans', 'WenQuanYi Zen Hei'],
ha='center'
)
( Código fuente , png )
Internamente, esto se implementa configurando la "familia de fuentes" en los
FontProperties
objetos en una lista de familias de fuentes. Una API privada (actualmente) extrae una lista de rutas a todas las fuentes encontradas y luego construye un único ft2font.FT2Font
objeto que reconoce todas las fuentes. Cada glifo de la cadena se representa con la primera fuente de la lista que contiene ese glifo.
La mayor parte de este trabajo fue realizado por Aitik Gupta con el apoyo de Google Summer of Code 2021.