6

I'm using matplotlib with its pgf backend to generate plots that I include in my LaTeX beamer document. I run into trouble when I use latex commands that are not defined. But for my application, I don't need matplotlib to generate the labels or annotations with latex, I only want a correct pgf output and I will call LaTeX on my beamer document. If I would run this code in a notebook, I would expect just to have a plot with a literal "\si{\percent}" in the xlabel.

In the MWE below, when I run it with the commented line (using \si{\percent}), matplotlib crashes with a latex error ('unknown command si'). I don't want to create a preamble with matplotlib, I just want the pgf output containing the \si{\percent} command...

If I use double backslashes, the code passes but the double backslash appears also in the pfg output and hence latex doesn't recognize the command (it sees a newline, I guess).

I don't understand the "value" of the plt.rc('text', usetex=False). I thought this would disable calling LaTeX alltogether...

import numpy as np
import matplotlib as mpl
mpl.use('pgf')
from matplotlib import pyplot as plt
from matplotlib import rc
plt.style.use('bmh')
plt.rc('pgf',rcfonts=False)
plt.rc('text', usetex=False)
x = np.linspace(0,100,101)
y = np.cos(x/100)*np.exp(-x/100)
plt.plot(x,y)
#plt.xlabel(r'value (\si{\percent})')
plt.xlabel(r'value (%)')
plt.savefig('test.pgf')
GertVdE
  • 1,153
  • 1
  • 7
  • 12

1 Answers1

2

Is there any reason why you're hesitant to include a preamble? Doing so makes for an easy solution. The following works for me:

import numpy as np
import matplotlib as mpl

mpl.use('pgf')

from matplotlib import pyplot as plt

pgf_with_latex = {
        'text.usetex': False,
        'pgf.rcfonts': False,
        "pgf.preamble": [
                r"\usepackage{siunitx}"
                ]
}

mpl.rcParams.update(pgf_with_latex)

plt.style.use('bmh')

x = np.linspace(0,100,101)
y = np.cos(x/100)*np.exp(-x/100)
plt.plot(x,y)

plt.xlabel(r'value (\si{\percent})')
plt.savefig('test.pgf')
jwalton
  • 5,286
  • 1
  • 18
  • 36
  • Thanks for the answer. I don't like the option to include the preamble, because I'd have to do it for all packages I want to use. It also feels uncomfortable to "maintain" the same list at multiple locations (I have 40+ plots that I make and use in my beamer presentation). – GertVdE Feb 08 '19 at 14:23
  • Unfortunately, yes, you'd have to include all the packages needed to typeset your plot. However, you wouldn't have to maintain this preamble in multiple locations. You could either alter the default matplotlibrc file or create your own, and call it at the beginning of your plotting routines; e.g. ```plt.style.use('mybeamer')``` – jwalton Feb 08 '19 at 14:29
  • 1
    But then I would still synchronize two files (the matplotlibrc and my latex beamer source). Is there no way to tell matplotlib to treat the labels, annotations as just plain text and "copy" this text to the pgf file (so that when I compile my latex, the latex commands are interpreted)? – GertVdE Feb 08 '19 at 14:39
  • Sorry, though what you desire seems very reasonable, I currently don't think there's any way to do it without resorting to altering the preamble. – jwalton Feb 09 '19 at 15:50