1

An example of matplotlibs pgf backaend with latex is here. Since I use it often, I would like to create a matplotlib style from this. Unfortunately we have to specify all the latex packages in the pgf.preamble as indicated in this question. For some reason the pgf.preamble option does not get updated from the style I created. How can I use it in a matplotlib style?

The style I have created:

~/.config/matplotlib/stylelib $ cat pgf_debug.mplstyle | egrep -v "^[ \t]*[#]" | egrep -v "^[ \t]*$"
font.family         : serif
text.usetex         : True  ## use latex for all text handling. The following fonts
axes.grid           : True   ## display grid or not
                                          ## Note the use of string escapes here ('1f77b4', instead of 1f77b4)
axes.xmargin        : 0  ## x margin.  See `axes.Axes.margins`
axes.ymargin        : 0  ## y margin See `axes.Axes.margins`
savefig.bbox        : tight     ## 'tight' or 'standard'.
savefig.pad_inches  : 0      ## Padding to be used when bbox is set to 'tight'
pgf.rcfonts : False
pgf.preamble :  [ "\\usepackage{siunitx}" ]

The code I use it:

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

print("\n".join(plt.style.available)) # My style is there!
mpl.use("pgf")
plt.style.use("pgf_debug")
x = np.linspace(0,1,num=50)
fig, ax = plt.subplots()
ax.plot(x,x)
ax.text(0.6,0.1,r"foo \SI{1}{\volt}")
fig.savefig("mplstyle_mwe.png")

The error message indicates that the siunitx package is not loaded:

ValueError: Error processing 'foo \SI{1}{\volt}'
LaTeX Output:
! Undefined control sequence.
<argument> ...0000}{12.000000}\selectfont foo \SI
                                                  {1}{\volt }
<*> ...0}{12.000000}\selectfont foo \SI{1}{\volt}}

No pages of output.
Transcript written on texput.log.

On the other hand, siunitx is loaded and the correct figure is generated if I load the properties with pyplots's rcParam.update() function:

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

mpl.use("pgf")
x = np.linspace(0,1,num=50)

plt.rcParams.update({
    "font.family": "serif",  # use serif/main font for text elements
    "text.usetex": True,     # use inline math for ticks
    "pgf.rcfonts": False,    # don't setup fonts from rc parameters
    "pgf.preamble": [
        "\\usepackage{siunitx}",          # load additional packages
        "\\usepackage{unicode-math}",   # unicode math setup
        r"\setmathfont{xits-math.otf}",
        r"\setmainfont{DejaVu Serif}",  # serif font via preamble
        ]
})
fig, ax = plt.subplots()
ax.plot(x,x)
ax.text(0.6,0.1,r"foo \SI{1}{\volt}")
fig.savefig("mplstyle_mwe2.png")

What am I doing wrong, and how could I use the style for pgf plots? I bonus question might be whether mpl.use("pgf") could be added to the style?

Horror Vacui
  • 195
  • 8

2 Answers2

0

I found the solution to this today when I came across the same problem. I think the key is that matplotlib doesn't want formatted strings in the style file (e.g. compare the font.family: serif entries in the above examples). The following style file should correctly load all the packages you want in the last example:

font.family: serif

text.usetex: True

pgf.rcfonts: False
pgf.preamble: \usepackage{siunitx}, \usepackage{unicode-math}, \setmathfont{xits-math.otf}, \setmainfont{DejaVu Serif}

I haven't managed to solve your bonus question, but at least the only setup needed now is mpl.use("pgf") and plt.style.use("mystyle")

  • For me, the comma separated value list doesn't work. I can do `pgf.preamble: \usepackage{siunitx}` but `pgf.preamble: \usepackage{siunitx}, \usepackage{mhchem}` fails with a lualatex compilation error – GertVdE Jul 09 '20 at 11:40
0

I had the same problem. I realised the way to make it work was to follow the advice given in "ChowlandGFD"'s answer, but to remove the comma seperating the seperate inputs. In other words, replace:

pgf.preamble: \usepackage{siunitx}, \usepackage{mhchem}

with:

pgf.preamble: \usepackage{siunitx} \usepackage{mhchem}

in the mplstyle file.

I determined this by comparing what the mplstyle file had set for rcParams['pgf.preamble'] with the equivalent value when setting the parameter via the command rcParams.update({'pgf.preamble': r'\usepackage{siunitx} \usepackage{mhchem}'}).

Note that pgf.preamble does not require a python list, and can use a string for multiple package imports.

Note also that this was tested with the following preceeding mplstyle commands:

font.family: sans-serif
text.usetex: True
pgf.rcfonts: False
pgf.texsystem: lualatex

and with mpl.use("pgf"); though not in the style file.

Steve0
  • 1
  • 1