7

I'm writing a LaTeX document and I include some matplotlib plots in it, in .pgf format with \include{file.pgf}. It has advantages over exporting the matplotlib plot to .pdf or .eps formats in that the fonts matches the one of my document and probably other advantages, but that is beside the main question.

In my LaTeX document I use the siunitx package, and I'd like to use it for the matplotlib plots too. For instance some axis might be the distance in meters, so I'd like to use Distance (\si{\meter}) instead of Distance (m).

From what I gathered from an extensive Google research, in the Python file .py, I came up with the following example:

import matplotlib as mpl
mpl.use('pgf')
mplparams = {"pgf.rcfonts": False}
mpl.rc('text', usetex=True)
mpl.rcParams.update(mplparams)
import matplotlib.pyplot as plt
plt.rc('text', usetex=True) 
if "siunitx" not in plt.rcParams["text.latex.preamble"]:
    plt.rcParams["text.latex.preamble"].append(r"\usepackage{siunitx}")

X = [0, 1, 2, 3, 4, 5]
Y = [-2, 7 , 3 , 8 , 7, 5]
plt.plot(X, Y)
plt.xlabel('Distance (\si{\meter})')
plt.savefig('file.pgf')

However it won't work and yields the error message:

  File "(...)\Anaconda3\lib\site-packages\matplotlib\backends\backend_pgf.py", line 375, in get_width_height_descent
    raise ValueError(msg % (text, e.latex_output))

ValueError: Error processing 'Distance (\si{\meter})'
LaTeX Output:
! Undefined control sequence.
<argument> ...12.000000}\selectfont Distance (\si 
                                              {\meter })
<*> ....000000}\selectfont Distance (\si{\meter})}

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

If I replace \si{\meter} by m, it does work.

I am therefore unable to use the siunitx package within Python. How could I make it work?

1 Answers1

15

This is probably not the correct place to ask this, as the question is about Matplotlib and Python not about LaTeX, IMHO. I use siunitx in the following way:

pgf_with_latex = {                      # setup matplotlib to use latex for output
    "pgf.texsystem": "pdflatex",        # change this if using xetex or lautex
    "text.usetex": True,                # use LaTeX to write all text
    "font.family": "serif",
    "font.serif": [],                   # blank entries should cause plots 
    "font.sans-serif": [],              # to inherit fonts from the document
    "font.monospace": [],
    "axes.labelsize": 10,               # LaTeX default is 10pt font.
    "font.size": 10,
    "legend.fontsize": 8,               # Make the legend/label fonts 
    "xtick.labelsize": 8,               # a little smaller
    "ytick.labelsize": 8,
    "figure.figsize": figsize(0.9),     # default fig size of 0.9 textwidth
    "pgf.preamble": "\n".join([ # plots will use this preamble
        r"\usepackage[utf8]{inputenc}",
        r"\usepackage[T1]{fontenc}",
        r"\usepackage[detect-all,locale=DE]{siunitx}",
        ])
    }
mpl.rcParams.update(pgf_with_latex)

So you'd have to update the pgf.preamble to include r"\usepackage{siunitx}".

Skillmon
  • 60,462
  • I wouldn't like to change this in the rcParams. Is there any other way I can do this? – MrT77 Aug 31 '22 at 11:46
  • 1
    @MrT77 setting the rcParams this way only changes this for the current Python run; and you can make another call to the rcParams to undo the changes later, if that's an issue. You don't have to alter your global parameters. (and if you're using .update you don't have to include all these parameters to change the few values you actually want to change). – Skillmon Aug 31 '22 at 11:47
  • How can I make the call to undo? In my case, I wasn't using pgf, but I need to use siunitx for a single figure. – MrT77 Aug 31 '22 at 11:50
  • 1
    @MrT77 maybe it's best to ask a new question for this, as I'm pretty unsure what you really do and need. As for the "how to undo" part: Save the settings you change before changing them in another dictionary and restore from that afterwards. – Skillmon Aug 31 '22 at 11:55
  • I just uploaded this question https://stackoverflow.com/questions/73557104/error-in-using-siunitx-with-matplotlib-python . Thanks in advance. – MrT77 Aug 31 '22 at 14:03