避免在 matplotlib 图的 PGF 导出中指定字体系列

Avoid specifying font family in PGF export of matplotlib figure

总结

我正在将 matplotlib 图形导出为 PGF 以在 LaTeX 中使用。

matplotlib 似乎在将图形另存为 PGF 时向每个文本条目(坐标轴标签、刻度、图例条目、注释)添加 \sffamily。这将阻止它从全局文档字体正确继承字体。

文本可以从全局文档字体继承字体,如果来自同一个系列,但如果全局字体来自不同系列,它将恢复为默认的 sffamily 字体。

我到了哪里

我相信我已经确定了问题:如果我编辑 PGF 文档并简单地删除任何文本条目的 \sffamily 部分,问题将不再存在并且全局字体被继承。删除不会阻止 LaTeX 正确编译它,我没有收到任何错误。

由于上述发现,我认为问题与 rcParams 或任何 LaTeX 序言无关(在 python 或实际的 LaTeX 文档中)。

MWE

我只是在尽可能简单的情节上进行了尝试,并且能够重现问题:

import matplotlib.pyplot as plt

fig = plt.figure()
plt.xlabel('a label')
fig.savefig('fig.pgf')

并且 pgf 文档将包含以下行:

\pgftext[x=3.280000in,y=0.240809in,,top]{\color{textcolor}\sffamily\fontsize{10.000000}{12.000000}\selectfont a label}%

所以添加了\sffamily。在 LaTeX 中呈现它会强制使用无衬线字体。删除 \sffamily 并渲染它将允许它继承字体系列。

TLDR

有没有办法避免在 matplotlib 的 PGF 输出中包含字体系列?

我无法提供解决方案,只能提供基于@samcarter 评论的解决方法:您可以在本地重新定义 \sffamily,例如:

\documentclass{article}

\usepackage{pgf}
\usepackage{fontspec}
\setmainfont{DejaVu Serif}
\setsansfont{DejaVu Sans}
\setmonofont{DejaVu Sans Mono}

\begin{document}
Lorem ipsum {\sffamily Lorem ipsum}
\begin{center}
    \renewcommand\sffamily{}
    \input{fig.pgf}
\end{center}
Lorem ipsum {\sffamily Lorem ipsum}
\end{document}

您可以使用任何环境或 \begingroup\endgroup

而不是 center

https://matplotlib.org/users/pgf.html#font-specification 的基础上,您可以使用:

import matplotlib as mpl
import matplotlib.pyplot as plt

pgf_with_rc_fonts = {
    "font.family": "serif",
}
mpl.rcParams.update(pgf_with_rc_fonts)


fig = plt.figure()
plt.xlabel('a label')
fig.savefig('fig.pgf')

这样用\rmfamily代替\sffamily

还有另一种解决方法,即在将 pgf 文件导入 tex 文档之前用 sed 替换字体规范。

\documentclass{article}
\usepackage{pgf}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usepackage{filecontents}

\begin{document}
\begin{figure}
    \begin{filecontents*}{tmpfile.sed}
# sed command file
s/\color{textcolor}\sffamily\fontsize{.*}{.*}\selectfont //\end{filecontents*}
    \immediate\write18{sed -i -f tmpfile.sed yourplot.pgf}
    \import{yourplot.pgf}
\end{figure}
\end{document}