Skip to content

Commit bc13abf

Browse files
authored
Merge pull request matplotlib#26893 from Socob/fix-pgf-fontsize
PGF: Consistently set LaTeX document font size
2 parents 67aee6c + f305f5f commit bc13abf

File tree

3 files changed

+51
-7
lines changed

3 files changed

+51
-7
lines changed

lib/matplotlib/backends/backend_pgf.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,37 +23,55 @@
2323
_create_pdf_info_dict, _datetime_to_pdf)
2424
from matplotlib.path import Path
2525
from matplotlib.figure import Figure
26+
from matplotlib.font_manager import FontProperties
2627
from matplotlib._pylab_helpers import Gcf
2728

2829
_log = logging.getLogger(__name__)
2930

3031

32+
_DOCUMENTCLASS = r"\documentclass{article}"
33+
34+
3135
# Note: When formatting floating point values, it is important to use the
3236
# %f/{:f} format rather than %s/{} to avoid triggering scientific notation,
3337
# which is not recognized by TeX.
3438

3539
def _get_preamble():
3640
"""Prepare a LaTeX preamble based on the rcParams configuration."""
41+
font_size_pt = FontProperties(
42+
size=mpl.rcParams["font.size"]
43+
).get_size_in_points()
3744
return "\n".join([
3845
# Remove Matplotlib's custom command \mathdefault. (Not using
3946
# \mathnormal instead since this looks odd with Computer Modern.)
4047
r"\def\mathdefault#1{#1}",
4148
# Use displaystyle for all math.
4249
r"\everymath=\expandafter{\the\everymath\displaystyle}",
50+
# Set up font sizes to match font.size setting.
51+
# If present, use the KOMA package scrextend to adjust the standard
52+
# LaTeX font commands (\tiny, ..., \normalsize, ..., \Huge) accordingly.
53+
# Otherwise, only set \normalsize, manually.
54+
r"\IfFileExists{scrextend.sty}{",
55+
r" \usepackage[fontsize=%fpt]{scrextend}" % font_size_pt,
56+
r"}{",
57+
r" \renewcommand{\normalsize}{\fontsize{%f}{%f}\selectfont}"
58+
% (font_size_pt, 1.2 * font_size_pt),
59+
r" \normalsize",
60+
r"}",
4361
# Allow pgf.preamble to override the above definitions.
4462
mpl.rcParams["pgf.preamble"],
45-
r"\ifdefined\pdftexversion\else % non-pdftex case.",
46-
r" \usepackage{fontspec}",
4763
*([
64+
r"\ifdefined\pdftexversion\else % non-pdftex case.",
65+
r" \usepackage{fontspec}",
66+
] + [
4867
r" \%s{%s}[Path=\detokenize{%s/}]"
4968
% (command, path.name, path.parent.as_posix())
5069
for command, path in zip(
5170
["setmainfont", "setsansfont", "setmonofont"],
5271
[pathlib.Path(fm.findfont(family))
5372
for family in ["serif", "sans\\-serif", "monospace"]]
5473
)
55-
] if mpl.rcParams["pgf.rcfonts"] else []),
56-
r"\fi",
74+
] + [r"\fi"] if mpl.rcParams["pgf.rcfonts"] else []),
5775
# Documented as "must come last".
5876
mpl.texmanager._usepackage_if_not_loaded("underscore", option="strings"),
5977
])
@@ -94,6 +112,8 @@ def _escape_and_apply_props(s, prop):
94112
family = prop.get_family()[0]
95113
if family in families:
96114
commands.append(families[family])
115+
elif not mpl.rcParams["pgf.rcfonts"]:
116+
commands.append(r"\fontfamily{\familydefault}")
97117
elif any(font.name == family for font in fm.fontManager.ttflist):
98118
commands.append(
99119
r"\ifdefined\pdftexversion\else\setmainfont{%s}\rmfamily\fi" % family)
@@ -185,7 +205,7 @@ class LatexManager:
185205
@staticmethod
186206
def _build_latex_header():
187207
latex_header = [
188-
r"\documentclass{article}",
208+
_DOCUMENTCLASS,
189209
# Include TeX program name as a comment for cache invalidation.
190210
# TeX does not allow this to be the first line.
191211
rf"% !TeX program = {mpl.rcParams['pgf.texsystem']}",
@@ -814,7 +834,7 @@ def print_pdf(self, fname_or_fh, *, metadata=None, **kwargs):
814834
self.print_pgf(tmppath / "figure.pgf", **kwargs)
815835
(tmppath / "figure.tex").write_text(
816836
"\n".join([
817-
r"\documentclass[12pt]{article}",
837+
_DOCUMENTCLASS,
818838
r"\usepackage[pdfinfo={%s}]{hyperref}" % pdfinfo,
819839
r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}"
820840
% (w, h),
@@ -924,7 +944,7 @@ def _write_header(self, width_inches, height_inches):
924944
pdfinfo = ','.join(
925945
_metadata_to_str(k, v) for k, v in self._info_dict.items())
926946
latex_header = "\n".join([
927-
r"\documentclass[12pt]{article}",
947+
_DOCUMENTCLASS,
928948
r"\usepackage[pdfinfo={%s}]{hyperref}" % pdfinfo,
929949
r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}"
930950
% (width_inches, height_inches),
Binary file not shown.

lib/matplotlib/tests/test_backend_pgf.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,3 +406,27 @@ def test_sketch_params():
406406
# \pgfdecoratecurrentpath must be after the path definition and before the
407407
# path is used (\pgfusepath)
408408
assert baseline in buf
409+
410+
411+
# test to make sure that the document font size is set consistently (see #26892)
412+
@needs_pgf_xelatex
413+
@pytest.mark.skipif(
414+
not _has_tex_package('unicode-math'), reason='needs unicode-math.sty'
415+
)
416+
@pytest.mark.backend('pgf')
417+
@image_comparison(['pgf_document_font_size.pdf'], style='default', remove_text=True)
418+
def test_document_font_size():
419+
mpl.rcParams.update({
420+
'pgf.texsystem': 'xelatex',
421+
'pgf.rcfonts': False,
422+
'pgf.preamble': r'\usepackage{unicode-math}',
423+
})
424+
plt.figure()
425+
plt.plot([],
426+
label=r'$this is a very very very long math label a \times b + 10^{-3}$ '
427+
r'and some text'
428+
)
429+
plt.plot([],
430+
label=r'\normalsize the document font size is \the\fontdimen6\font'
431+
)
432+
plt.legend()

0 commit comments

Comments
 (0)