From 23e0b0cf4a04ad7566089fb4d2904837e6d6292d Mon Sep 17 00:00:00 2001 From: MiniX16 Date: Sun, 18 May 2025 01:13:33 +0200 Subject: [PATCH 1/5] Add support for pgf.documentclass rcParam --- lib/matplotlib/__init__.py | 1 + lib/matplotlib/backends/backend_pgf.py | 4 +++- lib/matplotlib/rcsetup.py | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 9abc6c5a84dd..f52baec79cbf 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -958,6 +958,7 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True): # Strip leading comment. transform=lambda line: line[1:] if line.startswith("#") else line, fail_on_error=True) +rcParamsDefault["pgf.documentclass"] = "article" rcParamsDefault._update_raw(rcsetup._hardcoded_defaults) rcParamsDefault._ensure_has_backend() diff --git a/lib/matplotlib/backends/backend_pgf.py b/lib/matplotlib/backends/backend_pgf.py index 48b6e8ac152c..bc4f50d6dfa2 100644 --- a/lib/matplotlib/backends/backend_pgf.py +++ b/lib/matplotlib/backends/backend_pgf.py @@ -29,7 +29,9 @@ _log = logging.getLogger(__name__) -_DOCUMENTCLASS = r"\documentclass{article}" +_DOCUMENTCLASS = ( + rf"\documentclass{{{mpl.rcParams.get('pgf.documentclass', 'article')}}}" +) # Note: When formatting floating point values, it is important to use the diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index ce29c5076100..30caac62a872 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -1336,6 +1336,7 @@ def _convert_validator_spec(key, conv): "pgf.texsystem": ["xelatex", "lualatex", "pdflatex"], # latex variant used "pgf.rcfonts": validate_bool, # use mpl's rc settings for font config "pgf.preamble": validate_string, # custom LaTeX preamble + "pgf.documentclass": validate_string, # LaTeX document class used by PGF backend # write raster image data into the svg file "svg.image_inline": validate_bool, From e8f44bce592e5b4631cd0f1175d8c269c3b46707 Mon Sep 17 00:00:00 2001 From: MiniX16 Date: Sun, 18 May 2025 15:40:40 +0200 Subject: [PATCH 2/5] Add pgf.documentclass default to matplotlibrc template --- lib/matplotlib/mpl-data/matplotlibrc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/matplotlib/mpl-data/matplotlibrc b/lib/matplotlib/mpl-data/matplotlibrc index acb131c82e6c..3317c7a3ff0b 100644 --- a/lib/matplotlib/mpl-data/matplotlibrc +++ b/lib/matplotlib/mpl-data/matplotlibrc @@ -762,6 +762,7 @@ #pgf.rcfonts: True #pgf.preamble: # See text.latex.preamble for documentation #pgf.texsystem: xelatex +#pgf.documentclass: article ### docstring params #docstring.hardcopy: False # set this when you want to generate hardcopy docstring From 1bf0be7f6244bc85192ea4c65c3691c23c8824f4 Mon Sep 17 00:00:00 2001 From: MiniX16 Date: Sun, 18 May 2025 17:19:09 +0200 Subject: [PATCH 3/5] Refactor _DOCUMENTCLASS variable to inline pgf.documentclass access --- lib/matplotlib/backends/backend_pgf.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/backends/backend_pgf.py b/lib/matplotlib/backends/backend_pgf.py index bc4f50d6dfa2..94014b269503 100644 --- a/lib/matplotlib/backends/backend_pgf.py +++ b/lib/matplotlib/backends/backend_pgf.py @@ -29,11 +29,6 @@ _log = logging.getLogger(__name__) -_DOCUMENTCLASS = ( - rf"\documentclass{{{mpl.rcParams.get('pgf.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. @@ -207,7 +202,7 @@ class LatexManager: @staticmethod def _build_latex_header(): latex_header = [ - _DOCUMENTCLASS, + rf"\documentclass{{{mpl.rcParams.get('pgf.documentclass', 'article')}}}", # 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']}", @@ -833,10 +828,11 @@ def print_pdf(self, fname_or_fh, *, metadata=None, **kwargs): # print figure to pgf and compile it with latex with TemporaryDirectory() as tmpdir: tmppath = pathlib.Path(tmpdir) + docclass = mpl.rcParams.get("pgf.documentclass", "article") self.print_pgf(tmppath / "figure.pgf", **kwargs) (tmppath / "figure.tex").write_text( "\n".join([ - _DOCUMENTCLASS, + rf"\documentclass{{{docclass}}}" r"\usepackage[pdfinfo={%s}]{hyperref}" % pdfinfo, r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}" % (w, h), @@ -933,7 +929,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([ - _DOCUMENTCLASS, + rf"\documentclass{{{mpl.rcParams.get('pgf.documentclass', 'article')}}}", r"\usepackage[pdfinfo={%s}]{hyperref}" % pdfinfo, r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}" % (width_inches, height_inches), From 89f6d80f63d2044389eeb98a95f33af985178584 Mon Sep 17 00:00:00 2001 From: MiniX16 Date: Mon, 19 May 2025 00:18:32 +0200 Subject: [PATCH 4/5] doc: new pgf.documentclass rcParam and add release note --- doc/users/next_whats_new/pgf-documentclass.rst | 8 ++++++++ galleries/users_explain/text/pgf.py | 13 +++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 doc/users/next_whats_new/pgf-documentclass.rst diff --git a/doc/users/next_whats_new/pgf-documentclass.rst b/doc/users/next_whats_new/pgf-documentclass.rst new file mode 100644 index 000000000000..0d4c80d7561d --- /dev/null +++ b/doc/users/next_whats_new/pgf-documentclass.rst @@ -0,0 +1,8 @@ +PGF backend: new rcParam :rc:`pgf.documentclass` +------------------------------------------------ + +A new rcParam :rc:`pgf.documentclass` has been added to allow users to override +the default LaTeX document class (``article``) used by the PGF backend. +This enables better compatibility when including PGF figures in documents that +use custom LaTeX classes like ``IEEEtran`` or others, avoiding layout +issues like incorrect font sizes or spacing mismatches. diff --git a/galleries/users_explain/text/pgf.py b/galleries/users_explain/text/pgf.py index c5fa16f35ce7..6b5b0eacb63a 100644 --- a/galleries/users_explain/text/pgf.py +++ b/galleries/users_explain/text/pgf.py @@ -48,6 +48,7 @@ pgf.preamble Lines to be included in the LaTeX preamble pgf.rcfonts Setup fonts from rc params using the fontspec package pgf.texsystem Either "xelatex" (default), "lualatex" or "pdflatex" +pgf.documentclass The LaTeX document class to use (e.g., "article", "IEEEtran") ================= ===================================================== .. note:: @@ -144,6 +145,7 @@ if you want to do the font configuration yourself instead of using the fonts specified in the rc parameters, make sure to disable :rc:`pgf.rcfonts`. + .. code-block:: python import matplotlib as mpl @@ -170,6 +172,17 @@ ax.set_ylabel(r"\url{https://matplotlib.org}") ax.legend(["unicode math: $λ=∑_i^∞ μ_i^2$"]) +You can also change the LaTeX document class used when generating PGF figures. +By default, Matplotlib uses ``article``, but you can override this using +the ``pgf.documentclass`` rcParam:: + + import matplotlib.pyplot as plt + plt.rcParams["pgf.documentclass"] = "IEEEtran" + +This is useful when including PGF figures into LaTeX documents using +custom classes such as ``IEEEtran``, to avoid layout +mismatches in font size or spacing. + .. redirect-from:: /gallery/userdemo/pgf_texsystem .. _pgf-texsystem: From 6d48325cf452564c5208d500fa03c35309913364 Mon Sep 17 00:00:00 2001 From: MiniX16 Date: Mon, 19 May 2025 00:50:30 +0200 Subject: [PATCH 5/5] Add test for pgf.documentclass rcParam in PGF backend --- lib/matplotlib/tests/test_backend_pgf.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/matplotlib/tests/test_backend_pgf.py b/lib/matplotlib/tests/test_backend_pgf.py index e218a81cdceb..661ae2d3a59e 100644 --- a/lib/matplotlib/tests/test_backend_pgf.py +++ b/lib/matplotlib/tests/test_backend_pgf.py @@ -400,3 +400,12 @@ def test_document_font_size(): label=r'\normalsize the document font size is \the\fontdimen6\font' ) plt.legend() + + +@pytest.mark.backend("pgf") +def test_pgf_documentclass_written(): + from matplotlib.backends.backend_pgf import LatexManager + + mpl.rcParams["pgf.documentclass"] = "IEEEtran" + header = LatexManager._build_latex_header() + assert r"\documentclass{IEEEtran}" in header