FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Matplotlib chooses the wrong font for unrecognized weights · Issue #8550 · matplotlib/matplotlib · GitHub

Repository navigation

Matplotlib chooses the wrong font for unrecognized weights #8550

Closed

Description

Bug report

Bug summary

With a lot of the modern fonts containing exotic font weights like “Thin” or “Ultra bold”, matplotlib will sometimes pick the wrong font weight because it assumes that any font weight that it doesn’t recognize is either normal (400) or bold (700), even though there is a “Regular” available. Ultimately which one matplotlib picks seems to be actually kind of random, probably depending on the order in which the fonts appear in the font cache.

This is what the logic in font_manager.py looks like:

weight = next((w for w in weight_dict if sfnt4.find(w) >= 0), None)
if not weight:
    if font.style_flags & ft2font.BOLD:
        weight = 700
    else:
        weight = 400

sfnt4 appears to be a string that contains the full name of the font, including the weight. The problem with this approach is that if it doesn’t recognize the weight, it will simply assume the weight is either 400 or 700. A “Thin” font that was mistakenly labeled 400 might get picked over a “Regular” font.

Here are all the weights currently recognized:

weight_dict = {
    'ultralight' : 100,
    'light'      : 200,
    'normal'     : 400,
    'regular'    : 400,
    'book'       : 400,
    'medium'     : 500,
    'roman'      : 500,
    'semibold'   : 600,
    'demibold'   : 600,
    'demi'       : 600,
    'bold'       : 700,
    'heavy'      : 800,
    'extra bold' : 800,
    'black'      : 900}

I imagine we could add “Thin” and some others into the list, but I don’t think this solves the fundamental problem that fonts with unrecognized weights are presumed “Regular”/“Bold” and do not have lower precedence than fonts that are definitely “Regular”/“Bold”.

TL;DR: It would be nice to have a more robust way to detect font weights and handle unknown font weights.

Matplotlib version

  • Operating System: Arch Linux
  • Matplotlib Version: HEAD
  • Python Version: 3.6.0
  • Jupyter Version (if applicable): n/a
  • Other Libraries: n/a

Activity

  1. added this to the milestone on May 2, 2017
  2. Rufflewind commented on Jun 26, 2017

    ContributorAuthor

    This is a bit of "wish" but I think it would nice to have the option to specify the subfamily explicitly, in case the subfamily is really exotic. So I should be able to pass e.g. font="Fira Sans Four" and get the Four subfamily. (Either parse the subfamily from the user-provided string, or have a second attribute font_subfamily, which is arguably more principled.)

    (@tacaswell)

  3. tacaswell commented on Jun 26, 2017

    Member

    Can you even do that with the font-config tools? That seems like a difficult parsing problem as the space is used to both in the family name (which I think in 'Fire Sans') and to separate the sub-family.

    There is a PR from @mdboom to replace our home-grown font selection with font-config around...

  4. Rufflewind commented on Jun 26, 2017

    ContributorAuthor

    Looks like font-config uses a colon:

    $ fc-match 'Fira Sans'        
    FiraSans-Regular.ttf: "Fira Sans" "Regular"
    $ fc-match 'Fira Sans: Italic'
    FiraSans-Italic.ttf: "Fira Sans" "Italic"
    

    (I'm actually surprised that font-config even recognizes subfamily)

  5. modified the milestones: , on Sep 24, 2017
  6. anntzer commented on Dec 6, 2018

    Contributor

    https://github.com/anntzer/mplfccache should allow you to regenerate the font cache using the metadata provided by fontconfig (obviously, this depends on fontconfig utilities being available in the $PATH).

    I also have a Python reimplementation of (most of) fontconfig's logic (translated from source) in https://github.com/anntzer/freetypybind/blob/master/lib/freetypybind/query_face.py#L499, just needs some packaging effort...

  7. anntzer commented on May 28, 2020

    Contributor

    #16203 fixes most of this. I think the "direct access to subfamily request" is tracked by #4822.

  8. modified the milestones: needs sorting, v3.3.0 on May 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL