Skip to content

Fix issue with PGF backend not falling back to default LaTeX fonts. #22111

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

oscargus
Copy link
Member

@oscargus oscargus commented Jan 5, 2022

PR Summary

Fixes #20850
Closes #20945

Seems like a minor fix, so not "What's new" required?

PR Checklist

Tests and Styling

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (install flake8-docstrings and run flake8 --docstring-convention=all).

Documentation

  • New features are documented, with examples if plot related.
  • New features have an entry in doc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).

@oscargus oscargus changed the title Updated example to actually use PGF backend. Fixed issue with PGF backend not falling back to default LaTeX fonts. Jan 5, 2022
@oscargus
Copy link
Member Author

oscargus commented Jan 5, 2022

The main question is if it should fall back to LaTeX or matplotlibfonts in general. Now it will always fall back to LaTeX rather than matplotlib (which doesn't seem to work properly on my Windows machine anyway...).

@oscargus oscargus marked this pull request as draft January 5, 2022 17:10
@oscargus oscargus changed the title Fixed issue with PGF backend not falling back to default LaTeX fonts. Fix issue with PGF backend not falling back to default LaTeX fonts. Jul 7, 2022
@oscargus
Copy link
Member Author

oscargus commented Jul 7, 2022

I updated it, but now (I do not recall the previous status), we instead get a different warning message (and no plot shown):

https://output.circle-artifacts.com/output/job/cf13447f-3f64-4525-b922-393905dac3b6/artifacts/0/doc/build/html/gallery/userdemo/pgf_fonts.html?highlight=pgf

@anntzer
Copy link
Contributor

anntzer commented Jul 10, 2022

Good catch, the error makes sense, we need something like

diff --git i/lib/matplotlib/backends/backend_pgf.py w/lib/matplotlib/backends/backend_pgf.py
index 255714a7ea..a8f2587b9e 100644
--- i/lib/matplotlib/backends/backend_pgf.py
+++ w/lib/matplotlib/backends/backend_pgf.py
@@ -151,16 +151,27 @@ def _escape_and_apply_props(s, prop):
     """
     commands = []
 
-    families = {"serif": r"\rmfamily", "sans": r"\sffamily",
-                "sans-serif": r"\sffamily", "monospace": r"\ttfamily"}
+    standard_families = {
+        "serif": r"\rmfamily",
+        "sans": r"\sffamily",  # Doesn't match FontManager, perhaps deprecate?
+        "sans-serif": r"\sffamily",
+        "sans serif": r"\sffamily",
+        "monospace": r"\ttfamily",
+    }
     family = prop.get_family()[0]
-    if family in families:
-        commands.append(families[family])
-    elif (any(font.name == family for font in fm.fontManager.ttflist)
-          and mpl.rcParams["pgf.texsystem"] != "pdflatex"):
-        commands.append(r"\setmainfont{%s}\rmfamily" % family)
+    if family in standard_families:
+        commands.append(standard_families[family])
     else:
-        _log.warning("Ignoring unknown font: %s", family)
+        if family in fm.font_family_aliases:  # Only cursive & fantasy remain.
+            path = fm.findfont(family)
+            names = [fe.name for fe in fm.fontManager.ttflist
+                     if fe.fname == path]
+            family = names[0]
+        if (any(font.name == family for font in fm.fontManager.ttflist)
+                and mpl.rcParams["pgf.texsystem"] != "pdflatex"):
+            commands.append(r"\setmainfont{%s}\rmfamily" % family)
+        else:
+            _log.warning("Ignoring unknown font: %s", family)
 
     size = prop.get_size_in_points()
     commands.append(r"\fontsize{%f}{%f}" % (size, size * 1.2))

(Perhaps nicer would be to have a variant of findfont which directly returns the correct FontEntry rather than just the path, as this avoids having to try to get back to the FontEntry from the path which may fail if we don't have a bijection. Also once we have both the family and the path, we can additionally explicitly set the font path for tex similarly to how it's already done in _get_preamble.)

# with backslashes.
# 2) The dirname needs to include a separator.
path = pathlib.Path(fm.findfont(family,
fallback_to_default=False))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor nit: only the findfont call should be wrapped in the try... except; this makes it clearer that you're catching failures of findfont and not e.g. findfont returning an invalid value for Path(). (Plus this avoids the awkward linebreak.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: Warning: Font Family not found
2 participants