如何为matplotlib安装草书字体:找不到字体系列['cursive']

2024-05-14 23:33:13 发布

您现在位置:Python中文网/ 问答频道 /正文

当尝试在Ubuntu 20.04上运行使用matplotlib中的草书字体的脚本(在下面的最小工作示例中给出)时,我收到了matplotlib警告:

findfont: Font family ['cursive'] not found. Falling back to DejaVu Sans.

这说明我没有任何matplotlib想要用于the cursive font family的草书字体。 当matplotlib的字体管理器或fc-list找不到任何草书字体时,下面的最小失败示例似乎证实了这一点

# on my local machine
$ fc-list : family | grep -i "chancery\|textile\|sand\|script\|felipa\|cursive"
URW Chancery L
Free Chancery

如何通过编程在Ubuntu上查找和安装这些字体?我知道我可以在internet上查找免费版本,但是如果我想在Docker映像上获取它们,我如何通过类似apt-get的CLI API安装它们

最小失败示例

对于以下Dockerfile

FROM ubuntu:20.04

RUN apt-get update -y && \
    apt-get install -y \
        fontconfig \
        fonts-dejavu \
        fonts-freefont-ttf \
        python3 \
        python3-dev \
        python3-pip \
        python3-venv \
        vim && \
        apt-get -y autoclean && \
        apt-get -y autoremove && \
        rm -rf /var/lib/apt/lists/*

RUN python3 -m pip install --upgrade --no-cache-dir pip setuptools wheel && \
    python3 -m pip install --no-cache-dir "matplotlib~=3.3" && \
    python3 -m pip list && \
    python3 -c "import matplotlib.pyplot" # generate font list cache

ENV MPLCONFIGDIR /tmp/.config # make writeable to non-root user

WORKDIR /code

COPY example.py example.py

example.py

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager


def make_plot(font_family):
    fig, ax = plt.subplots()
    x = np.linspace(0, 10, 101)
    y = np.square(x)
    ax.plot(x, y)
    ax.semilogy()

    ax.set_xlabel("$x$")
    ax.set_ylabel("$x^2$")
    ax.set_title(f"Default matplotlib settings for {font_family} font family")

    return fig, ax


def main():

    image_types = ["pdf", "png"]
    for font_family in ["sans-serif", "serif", "cursive"]:
        plt.rcParams.update({"font.family": font_family})
        fig, ax = make_plot(font_family=font_family)

        for type in image_types:
            fig.savefig(f"family_{font_family}.{type}")

    cursive_family = matplotlib.rcParams["font.cursive"]
    print(f"\nmatplotlib cursive family: {cursive_family}")
    tff_fonts = sorted(
        set([font.name for font in matplotlib.font_manager.fontManager.ttflist])
    )
    afm_fonts = sorted(
        set([font.name for font in matplotlib.font_manager.fontManager.afmlist])
    )
    all_fonts = sorted(set([*tff_fonts, *afm_fonts]))
    print(f"\ntff fonts: {tff_fonts}")
    print(f"\nafm fonts: {afm_fonts}")
    print(f"\nall fonts: {all_fonts}")
    found_cursive_fonts = [font for font in cursive_family if font in all_fonts]
    print(f"\nfound cursive fonts: {found_cursive_fonts}")


if __name__ == "__main__":
    main()

如果用

docker build . \
--pull \
-f Dockerfile \
-t matplotlib-cursive-fonts-question:debug-local

然后和我一起跑

$ docker run --rm --user 1000:1000 -v $PWD:$PWD -w $PWD matplotlib-cursive-fonts-question:debug-local /bin/bash -c "python3 /code/example.py"
findfont: Font family ['cursive'] not found. Falling back to DejaVu Sans.
findfont: Font family ['cursive'] not found. Falling back to DejaVu Sans.

matplotlib cursive family: ['Apple Chancery', 'Textile', 'Zapf Chancery', 'Sand', 'Script MT', 'Felipa', 'cursive']

tff fonts: ['DejaVu Math TeX Gyre', 'DejaVu Sans', 'DejaVu Sans Display', 'DejaVu Sans Mono', 'DejaVu Serif', 'DejaVu Serif Display', 'FreeMono', 'FreeSans', 'FreeSerif', 'STIXGeneral', 'STIXNonUnicode', 'STIXSizeFiveSym', 'STIXSizeFourSym', 'STIXSizeOneSym', 'STIXSizeThreeSym', 'STIXSizeTwoSym', 'cmb10', 'cmex10', 'cmmi10', 'cmr10', 'cmss10', 'cmsy10', 'cmtt10']

afm fonts: ['Computer Modern', 'Courier', 'Helvetica', 'ITC Avant Garde Gothic', 'ITC Bookman', 'ITC Zapf Chancery', 'ITC Zapf Dingbats', 'New Century Schoolbook', 'Palatino', 'Symbol', 'Times', 'Utopia', 'ZapfDingbats']

all fonts: ['Computer Modern', 'Courier', 'DejaVu Math TeX Gyre', 'DejaVu Sans', 'DejaVu Sans Display', 'DejaVu Sans Mono', 'DejaVu Serif', 'DejaVu Serif Display', 'FreeMono', 'FreeSans', 'FreeSerif', 'Helvetica', 'ITC Avant Garde Gothic', 'ITC Bookman', 'ITC Zapf Chancery', 'ITC Zapf Dingbats', 'New Century Schoolbook', 'Palatino', 'STIXGeneral', 'STIXNonUnicode', 'STIXSizeFiveSym', 'STIXSizeFourSym', 'STIXSizeOneSym', 'STIXSizeThreeSym', 'STIXSizeTwoSym', 'Symbol', 'Times', 'Utopia', 'ZapfDingbats', 'cmb10', 'cmex10', 'cmmi10', 'cmr10', 'cmss10', 'cmsy10', 'cmtt10']

found cursive fonts: []

docker run --rm --user 1000:1000 -v $PWD:$PWD -w $PWD matplotlib-cursive-fonts-question:debug-local /bin/bash -c "fc-list : family | grep -i 'chancery\|textile\|sand\|script\|felipa\|cursive'"

不返回任何内容

问题

如何通过编程找到并安装matplotlib(在Ubuntu 20.04上)所需的草书字体

相关链接


Tags: formatplotlib字体fontsaptaxfamilypython3
1条回答
网友
1楼 · 发布于 2024-05-14 23:33:13

由于似乎没有明确的方法从任何Ubuntu PPA获得这些字体,因此可以做的是直接从Google fonts下载Felipa,草书字体家族字体之一。这就是maptlotlib团队在^{} testing Docker image中所做的

因此,对于本地机器上的编程解决方案,我所能做的只是

mkdir -p ~/.local/share/fonts/truetype/felipa
wget  no-clobber https://github.com/google/fonts/blob/master/ofl/felipa/Felipa-Regular.ttf?raw=true -O ~/.local/share/fonts/truetype/felipa/Felipa-Regular.ttf
fc-cache  force  verbose # rebuild font cache for system
rm -rf ~/.cache/matplotlib/* # remove the matplotlib cache to force rebuild

虽然这不是必需的,但我还制作了一个符号链接,指向我的其他字体用于记账的位置

sudo ln -s "${HOME}/.local/share/fonts/truetype/felipa" /usr/share/fonts/truetype/felipa

当然,虽然这是程序化的,但如果您在本地计算机上并且具有交互功能,那么最好/更容易访问the Google Fonts page for Felipa,在本地下载字体系列zip文件并将其解压缩,然后用Ubuntu font manager 打开Felipa-Regular.ttf并让它为您安装

为了给这个工作提供一个可复制的示例,我已经将原始Dockerfile编辑为上面描述的wgetFelipa,然后还创建了一个非根用户“docker”,以使容器在默认情况下以非根用户的身份运行,并避免了在使用 user 1000:1000运行时没有HOME用户的问题。有很多方法可以使这个Dockerfile更加紧凑,但在这个例子中,我要考虑的是可读性,而不是大小优化

FROM ubuntu:20.04

RUN apt-get update -y && \
    apt-get install -y \
        fontconfig \
        fonts-dejavu \
        fonts-freefont-ttf \
        python3 \
        python3-dev \
        python3-pip \
        python3-venv \
        vim \
        wget && \
        apt-get -y autoclean && \
        apt-get -y autoremove && \
        rm -rf /var/lib/apt/lists/*

RUN python3 -m pip install  upgrade  no-cache-dir pip setuptools wheel && \
    python3 -m pip install  no-cache-dir "matplotlib~=3.3" && \
    python3 -m pip list

# Create user "docker"
RUN useradd -m docker && \
    cp /root/.bashrc /home/docker/
ENV HOME /home/docker

# felipa provides a cursive font
RUN mkdir -p "${HOME}/.local/share/fonts/truetype/felipa" && \
    wget  no-clobber "https://github.com/google/fonts/blob/master/ofl/felipa/Felipa-Regular.ttf?raw=true" -O "${HOME}/.local/share/fonts/truetype/felipa/Felipa-Regular.ttf" && \
    ln -s "${HOME}/.local/share/fonts/truetype/felipa" /usr/share/fonts/truetype/felipa && \
    fc-cache  force  verbose

WORKDIR /code

COPY example.py example.py

# give non-root user docker ownership of files
RUN chown -R  from=root docker /home/docker && \
    chown -R  from=root docker /code
USER docker

# Create font list cache and config dir
RUN python3 -c "import matplotlib.pyplot"

如前所述重新构建此Docker映像,然后允许在没有警告或错误的情况下运行以下操作

$ docker run  rm -v $PWD:$PWD -w $PWD matplotlib-cursive-fonts-question:debug-local /bin/bash -c "python3 /code/example.py"

matplotlib cursive family: ['Apple Chancery', 'Textile', 'Zapf Chancery', 'Sand', 'Script MT', 'Felipa', 'cursive']

tff fonts: ['DejaVu Math TeX Gyre', 'DejaVu Sans', 'DejaVu Sans Display', 'DejaVu Sans Mono', 'DejaVu Serif', 'DejaVu Serif Display', 'Felipa', 'FreeMono', 'FreeSans', 'FreeSerif', 'STIXGeneral', 'STIXNonUnicode', 'STIXSizeFiveSym', 'STIXSizeFourSym', 'STIXSizeOneSym', 'STIXSizeThreeSym', 'STIXSizeTwoSym', 'cmb10', 'cmex10', 'cmmi10', 'cmr10', 'cmss10', 'cmsy10', 'cmtt10']

afm fonts: ['Computer Modern', 'Courier', 'Helvetica', 'ITC Avant Garde Gothic', 'ITC Bookman', 'ITC Zapf Chancery', 'ITC Zapf Dingbats', 'New Century Schoolbook', 'Palatino', 'Symbol', 'Times', 'Utopia', 'ZapfDingbats']

all fonts: ['Computer Modern', 'Courier', 'DejaVu Math TeX Gyre', 'DejaVu Sans', 'DejaVu Sans Display', 'DejaVu Sans Mono', 'DejaVu Serif', 'DejaVu Serif Display', 'Felipa', 'FreeMono', 'FreeSans', 'FreeSerif', 'Helvetica', 'ITC Avant Garde Gothic', 'ITC Bookman', 'ITC Zapf Chancery', 'ITC Zapf Dingbats', 'New Century Schoolbook', 'Palatino', 'STIXGeneral', 'STIXNonUnicode', 'STIXSizeFiveSym', 'STIXSizeFourSym', 'STIXSizeOneSym', 'STIXSizeThreeSym', 'STIXSizeTwoSym', 'Symbol', 'Times', 'Utopia', 'ZapfDingbats', 'cmb10', 'cmex10', 'cmmi10', 'cmr10', 'cmss10', 'cmsy10', 'cmtt10']

found cursive fonts: ['Felipa']

family_cursive.png生成此绘图:

enter image description here

相关问题 更多 >

    热门问题