Description
Bug summary
When using the PGF backend, different LaTeX document font size settings are used when measuring widths vs. producing output. Although this is usually not a problem (since all text produced by the PGF backend locally sets the font properties), packages used in the custom preamble (such as unicode-math
) may depend on the font size settings, leading to incorrect width measurements since different outcomes are produced in the two cases.
Code for reproduction
import matplotlib
import matplotlib.pyplot as plt
matplotlib.use('pgf')
plt.rc('text', usetex=True) # not sure if this is actually relevant for PGF backend?
plt.rc('pgf', texsystem='lualatex', rcfonts=False, preamble=r'''
\usepackage{unicode-math}
''')
plt.figure()
plt.plot([], label=r'$this is a very very very long math label a \times b + 10^{-3}$ and some text')
plt.legend()
plt.savefig('test_math.png')
plt.savefig('test_math.pgf')
Actual outcome
Math text has a different width (characters are comparatively wider when scaled to the same height) and thus exceeds the legend boundary (tick labels also have some slight spacing issues):
Expected outcome
Text should be within the legend boundary:
Additional information
The main issue causing the problem in my example is that different font sizes are passed to \documentclass
in different cases:
matplotlib/lib/matplotlib/backends/backend_pgf.py
Lines 186 to 188 in ff552f4
This specific issue is only present in matplotlib ≥ v3.6.0 and seems to be a historical accident carried over from when the document class was changed from minimal
to article
in 4d85f70 (#23443). \documentclass{minimal}
actually ignores any options passed to it (including 12pt
), so that option in the original code was spurious and there was no mismatch between the cases with and without this option. But when this was changed to \documentclass{article}
, the option 12pt
did start taking effect, leading to the discrepancy.
However, more generally, the code always had an implicit dependence on the LaTeX font size setting, which does affect things like the unicode-math
package (which selects different versions of math fonts depending on the font size). So when saving as .pgf
and using these files directly in LaTeX documents, there is still the potential for problems to show up. Another consequence of this is that the standard LaTeX font size commands (\tiny
, …, \normalsize
, …, \Huge
) are also relative to this obscure font size setting (instead of rcParams['font.size']
).
Workaround for current releases: Manually set the font size in the preamble.
import matplotlib
import matplotlib.pyplot as plt
matplotlib.use('pgf')
plt.rc('text', usetex=True) # not sure if this is actually relevant for PGF backend?
plt.rc('pgf', texsystem='lualatex', rcfonts=False, preamble=r'''
\usepackage[fontsize=10pt]{scrextend}
\usepackage{unicode-math}
''')
plt.figure()
plt.plot([], label=r'$this is a very very very long math label a \times b + 10^{-3}$ and some text')
plt.legend()
plt.savefig('test_math.png')
plt.savefig('test_math.pgf')
Operating system
No response
Matplotlib Version
3.8.0
Matplotlib Backend
pgf
Python version
No response
Jupyter version
No response
Installation
pip