使用 Matplotlib 绘制字体表

Beginner

This tutorial is from open-source community. Access the source code

简介

Matplotlib 是 Python 中一个流行的数据可视化库。它通过 FreeType 库提供字体支持。在本实验中,我们将学习如何使用 Matplotlib 的 Axes.table 绘制给定字体的前 255 个字符的字体表。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。

打印字体中的字形

在这一步中,我们将定义一个函数 print_glyphs,它会将给定字体文件中的所有字形打印到标准输出。

import os
import unicodedata
import matplotlib.font_manager as fm
from matplotlib.ft2font import FT2Font

def print_glyphs(path):
    """
    将给定字体文件中的所有字形打印到标准输出。

    参数
    ----------
    path : str 或 None
        字体文件的路径。如果为 None,则使用 Matplotlib 的默认字体。
    """
    if path is None:
        path = fm.findfont(fm.FontProperties())  ## 默认字体。

    font = FT2Font(path)

    charmap = font.get_charmap()
    max_indices_len = len(str(max(charmap.values())))

    print("字体包含以下字形:")
    for char_code, glyph_index in charmap.items():
        char = chr(char_code)
        name = unicodedata.name(
                char,
                f"{char_code:#x} ({font.get_glyph_name(glyph_index)})")
        print(f"{glyph_index:>{max_indices_len}} {char} {name}")

绘制字体表

在这一步中,我们将定义一个函数 draw_font_table,用于绘制给定字体的前 255 个字符的字体表。

import os
from pathlib import Path
import unicodedata
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
from matplotlib.ft2font import FT2Font

def draw_font_table(path):
    """
    绘制给定字体的前 255 个字符的字体表。

    参数
    ----------
    path : str 或 None
        字体文件的路径。如果为 None,则使用 Matplotlib 的默认字体。
    """
    if path is None:
        path = fm.findfont(fm.FontProperties())  ## 默认字体。

    font = FT2Font(path)

    ## 获取字体的字符映射表
    codes = font.get_charmap().items()

    ## 创建表格的标签和单元格
    labelc = [f"{i:X}" for i in range(16)]
    labelr = [f"{i:02X}" for i in range(0, 16*16, 16)]
    chars = [["" for c in range(16)] for r in range(16)]

    for char_code, glyph_index in codes:
        if char_code >= 256:
            continue
        row, col = divmod(char_code, 16)
        chars[row][col] = chr(char_code)

    ## 使用 Matplotlib 的 Axes.table 绘制表格
    fig, ax = plt.subplots(figsize=(8, 4))
    ax.set_title(os.path.basename(path))
    ax.set_axis_off()

    table = ax.table(
        cellText=chars,
        rowLabels=labelr,
        colLabels=labelc,
        rowColours=["palegreen"] * 16,
        colColours=["palegreen"] * 16,
        cellColours=[[".95" for c in range(16)] for r in range(16)],
        cellLoc='center',
        loc='upper left',
    )

    ## 将表格单元格的字体设置为给定路径的字体
    for key, cell in table.get_celld().items():
        row, col = key
        if row > 0 and col > -1:  ## 注意表格特殊的索引方式...
            cell.set_text_props(font=Path(path))

    fig.tight_layout()
    plt.show()

显示字体表

在这一步中,我们将使用 argparse 从命令行参数中解析字体文件的路径。然后我们将调用 print_glyphs 来打印字体文件中的所有字形,并调用 draw_font_table 来绘制该字体的前 255 个字符的字体表。

if __name__ == "__main__":
    from argparse import ArgumentParser

    parser = ArgumentParser(description="Display a font table.")
    parser.add_argument("path", nargs="?", help="Path to the font file.")
    parser.add_argument("--print-all", action="store_true",
                        help="Additionally, print all chars to stdout.")
    args = parser.parse_args()

    if args.print_all:
        print_glyphs(args.path)
    draw_font_table(args.path)

总结

在本实验中,我们学习了如何使用 Matplotlib 的 Axes.table 绘制字体文件中前 255 个字符的字体表。我们定义了函数来打印字体文件中的所有字形以及绘制字体表。我们还使用了 argparse 从命令行参数中解析字体文件的路径。