11
votes

Summary

I am exporting matplotlib figures as PGF to use in LaTeX.

matplotlib seems to add a \sffamily addition to every text entry (axes labels, ticks, legend entries, annotations) when saving the figure as a PGF. This will stop it from properly inheriting the font from the global document font.

The text can inheret the font from the global document font if it is from the same family, but it will revert to the default sffamily font if the global font is from a different family.

Where I got to

I believe I have isolated the problem: if I edit the PGF document and simply remove the \sffamily part of any text entry, the problem no longer persists and the global font is inherited. The deletion doesn't prevent LaTeX from compiling it properly, and I get no errors.

Because of the above finding, I believe the problem has nothing to do with rcParams or any LaTeX preamble (both in python or in the actual LaTeX document).

MWE

I just tried it on the simplest possible plot and was able to reproduce the problem:

import matplotlib.pyplot as plt

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

And pgf document will contain the following line:

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

so the \sffamily is added. Rendering this in LaTeX will force a sans-serif font. Removing the \sffamily and rendering it will allow it to inherit the font family.

TLDR

Is there a way to avoid the inclusion of a font family in the PGF output of matplotlib?

3

3 Answers

3
votes

I cannot offer a solution but a workaround building on @samcarter's comment: You can redefine \sffamily locally, e.g.:

\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}

Instead of center you can use any environment or \begingroup and \endgroup.

2
votes

Building on https://matplotlib.org/users/pgf.html#font-specification you could use:

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')

This way \rmfamily is used instead of \sffamily.

2
votes

There is another workaround by replacing the font specification with sed before importing the pgf file in your tex-document.

\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}