-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
PGF: Consistently set LaTeX document font size #26893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
46ac87e
14a5900
8bf18f2
98673a0
896b280
4a4a41f
0fec213
6d49b51
f305f5f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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}{", | ||
Socob marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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.", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason for the change here and immediately below? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That’s 14a5900. I guess it’s only tangentially related to the rest of this PR, but I noticed that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the ability to exclude |
||
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 []), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... i.e. here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above. |
||
# Documented as "must come last". | ||
mpl.texmanager._usepackage_if_not_loaded("underscore", option="strings"), | ||
]) | ||
|
@@ -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) | ||
|
@@ -185,7 +205,7 @@ class LatexManager: | |
@staticmethod | ||
def _build_latex_header(): | ||
latex_header = [ | ||
r"\documentclass{article}", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these could have been left as they were originally (but removing the 12pt below) no? especially considering that we may want to make the documentclass configurable in the future, which would be more awkward to do if referencing a global. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what you mean? These all have to be identical, so introducing a single name for them is just DRY. And in fact one of the first things one would do when making the documentclass configurable. I don’t see how it matters whether it’s a global constant or something else – that can always be changed with no effort. The point is to use a single variable for things that have to be the same. |
||
_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']}", | ||
|
@@ -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), | ||
|
@@ -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), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I think I was mistaken with my comment that matplotlib uses |
||
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() |
Uh oh!
There was an error while loading. Please reload this page.