Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Bug]: PGF font size mismatch between measurement and output #26892

Copy link
Copy link
Closed
@Socob

Description

@Socob
Issue body actions

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):

MWE output showing the problem

Expected outcome

Text should be within the legend boundary:

Fixed MWE output

Additional information

The main issue causing the problem in my example is that different font sizes are passed to \documentclass in different cases:

def _build_latex_header():
latex_header = [
r"\documentclass{article}",

r"\documentclass[12pt]{article}",

r"\documentclass[12pt]{article}",

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.