I need to generate my matplotlib plots using lualatex instead of pdflatex. Among other things, I am using fontspec to change the document fonts. Below I am using this as an example and set lmroman10-regular.otf as the font. This creates a few issues. One is that the handles in the legends are not fully centered and are followed by some whitespace before the right border:  The python code generating the intermediate .pgf file looks like this: import matplotlib import numpy from matplotlib import pyplot x = numpy.linspace(-1, 1) y = x ** 2 matplotlib.rcParams["figure.figsize"] = (3, 2.5) matplotlib.rcParams["font.family"] = "serif" matplotlib.rcParams["font.size"] = 10 matplotlib.rcParams["legend.fontsize"] = 8 matplotlib.rcParams["pgf.texsystem"] = "lualatex" PREAMBLE = r"""\usepackage{ifluatex} \ifluatex \usepackage{fontspec} \setmainfont{lmroman10-regular.otf} \fi """ matplotlib.rcParams["text.latex.preamble"] = PREAMBLE matplotlib.rcParams["pgf.preamble"] = PREAMBLE matplotlib.rcParams["text.usetex"] = True pyplot.plot(x, y, label="this is the data") pyplot.legend() pyplot.xlabel("xlabel") pyplot.tight_layout() pyplot.savefig("lualatex_test.pgf")  The .pgf file is then embedded in a latex document. It seems it is not possible to directly compile to .pdf since then the document font will not be the selected font which can for example be seen by setting the font to someting more different like AntPoltExpd-Italic.otf. Also note note that the \ifluatex statement has to be added around the lualatex-only code since matplotlib uses pdflatex to determine the dimensions of text fragements, as will be seen below. For the sake of this simple example, the .tex file to render the .pgf may be just: \documentclass[11pt]{scrbook} \usepackage{pgf} \usepackage{fontspec} \setmainfont{lmroman10-regular.otf} \newcommand{\mathdefault}[1]{#1} \begin{document} \input{lualatex_test.pgf} \end{document}  which can be typeset using lualatex <filename> and results in the figure shown above (without the red arrow). I thought I had identified the reason for this but it seems I missed something. As mentioned above, matplotlib computes the dimensions of the text patches by actually placing them in a latex templated and compiling it using pdflatex. This happens in the matplotlib.texmanager.TexManager class in the corresponding file on the main branch for example. I thought I could fix it like this:  class TexManager: ... @classmethod def get_text_width_height_descent(cls, tex, fontsize, renderer=None): """Return width, height and descent of the text.""" if tex.strip() == '': return 0, 0, 0 dvifile = cls.make_dvi(tex, fontsize) dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1 with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi: page, = dvi # A total height (including the descent) needs to be returned. w = page.width # !!! if tex == "this is the data": w /= 1.14 print("fixed width") # !!! return w, page.height + page.descent, page.descent  which, to my understanding, should trick matplotlib into thinking the text is shorter by a factor of 1.14 (just a guess, should be adapted once the solution works). The code definitely gets called, since "fixed width" gets printed. But the gap is not fixed:  How can I fix this issue? How is matplotlib computing the legend content's width and can I maybe patch this to account for the correct width? Let's assume I know that the width error factor for the font size 8 is approximately 1.14. I can easily determine this for other fonts and font sizes.
It seems that when using custom font settings, you have to set the following rcParam: matplotlib.rcParams["pgf.rcfonts"] = False  Otherwise, if I understand it correctly, the font settings are applied from the rcParams. This solves the spacing issue with your example:  For more details, see also the documentation of the .pgf backend where this parameter is exaplained.