Skip to content

Commit

Permalink
Merge pull request #26893 from Socob/fix-pgf-fontsize
Browse files Browse the repository at this point in the history
PGF: Consistently set LaTeX document font size
  • Loading branch information
anntzer committed May 7, 2024
2 parents 67aee6c + f305f5f commit bc13abf
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 7 deletions.
34 changes: 27 additions & 7 deletions lib/matplotlib/backends/backend_pgf.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,55 @@
_create_pdf_info_dict, _datetime_to_pdf)
from matplotlib.path import Path
from matplotlib.figure import Figure
from matplotlib.font_manager import FontProperties
from matplotlib._pylab_helpers import Gcf

_log = logging.getLogger(__name__)


_DOCUMENTCLASS = r"\documentclass{article}"


# Note: When formatting floating point values, it is important to use the
# %f/{:f} format rather than %s/{} to avoid triggering scientific notation,
# which is not recognized by TeX.

def _get_preamble():
"""Prepare a LaTeX preamble based on the rcParams configuration."""
font_size_pt = FontProperties(
size=mpl.rcParams["font.size"]
).get_size_in_points()
return "\n".join([
# Remove Matplotlib's custom command \mathdefault. (Not using
# \mathnormal instead since this looks odd with Computer Modern.)
r"\def\mathdefault#1{#1}",
# Use displaystyle for all math.
r"\everymath=\expandafter{\the\everymath\displaystyle}",
# Set up font sizes to match font.size setting.
# If present, use the KOMA package scrextend to adjust the standard
# LaTeX font commands (\tiny, ..., \normalsize, ..., \Huge) accordingly.
# Otherwise, only set \normalsize, manually.
r"\IfFileExists{scrextend.sty}{",
r" \usepackage[fontsize=%fpt]{scrextend}" % font_size_pt,
r"}{",
r" \renewcommand{\normalsize}{\fontsize{%f}{%f}\selectfont}"
% (font_size_pt, 1.2 * font_size_pt),
r" \normalsize",
r"}",
# Allow pgf.preamble to override the above definitions.
mpl.rcParams["pgf.preamble"],
r"\ifdefined\pdftexversion\else % non-pdftex case.",
r" \usepackage{fontspec}",
*([
r"\ifdefined\pdftexversion\else % non-pdftex case.",
r" \usepackage{fontspec}",
] + [
r" \%s{%s}[Path=\detokenize{%s/}]"
% (command, path.name, path.parent.as_posix())
for command, path in zip(
["setmainfont", "setsansfont", "setmonofont"],
[pathlib.Path(fm.findfont(family))
for family in ["serif", "sans\\-serif", "monospace"]]
)
] if mpl.rcParams["pgf.rcfonts"] else []),
r"\fi",
] + [r"\fi"] if mpl.rcParams["pgf.rcfonts"] else []),
# Documented as "must come last".
mpl.texmanager._usepackage_if_not_loaded("underscore", option="strings"),
])
Expand Down Expand Up @@ -94,6 +112,8 @@ def _escape_and_apply_props(s, prop):
family = prop.get_family()[0]
if family in families:
commands.append(families[family])
elif not mpl.rcParams["pgf.rcfonts"]:
commands.append(r"\fontfamily{\familydefault}")
elif any(font.name == family for font in fm.fontManager.ttflist):
commands.append(
r"\ifdefined\pdftexversion\else\setmainfont{%s}\rmfamily\fi" % family)
Expand Down Expand Up @@ -185,7 +205,7 @@ class LatexManager:
@staticmethod
def _build_latex_header():
latex_header = [
r"\documentclass{article}",
_DOCUMENTCLASS,
# Include TeX program name as a comment for cache invalidation.
# TeX does not allow this to be the first line.
rf"% !TeX program = {mpl.rcParams['pgf.texsystem']}",
Expand Down Expand Up @@ -814,7 +834,7 @@ def print_pdf(self, fname_or_fh, *, metadata=None, **kwargs):
self.print_pgf(tmppath / "figure.pgf", **kwargs)
(tmppath / "figure.tex").write_text(
"\n".join([
r"\documentclass[12pt]{article}",
_DOCUMENTCLASS,
r"\usepackage[pdfinfo={%s}]{hyperref}" % pdfinfo,
r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}"
% (w, h),
Expand Down Expand Up @@ -924,7 +944,7 @@ def _write_header(self, width_inches, height_inches):
pdfinfo = ','.join(
_metadata_to_str(k, v) for k, v in self._info_dict.items())
latex_header = "\n".join([
r"\documentclass[12pt]{article}",
_DOCUMENTCLASS,
r"\usepackage[pdfinfo={%s}]{hyperref}" % pdfinfo,
r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}"
% (width_inches, height_inches),
Expand Down
Binary file not shown.
24 changes: 24 additions & 0 deletions lib/matplotlib/tests/test_backend_pgf.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,3 +406,27 @@ def test_sketch_params():
# \pgfdecoratecurrentpath must be after the path definition and before the
# path is used (\pgfusepath)
assert baseline in buf


# test to make sure that the document font size is set consistently (see #26892)
@needs_pgf_xelatex
@pytest.mark.skipif(
not _has_tex_package('unicode-math'), reason='needs unicode-math.sty'
)
@pytest.mark.backend('pgf')
@image_comparison(['pgf_document_font_size.pdf'], style='default', remove_text=True)
def test_document_font_size():
mpl.rcParams.update({
'pgf.texsystem': 'xelatex',
'pgf.rcfonts': False,
'pgf.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}$ '
r'and some text'
)
plt.plot([],
label=r'\normalsize the document font size is \the\fontdimen6\font'
)
plt.legend()

0 comments on commit bc13abf

Please sign in to comment.