3

When i use fontname= with the Humor Sans font I get this error:

/usr/lib/python3.5/site-packages/matplotlib/font_manager.py:1288: UserWarning: findfont: Font family ['Humor Sans', 'Comic Sans MS'] not found. Falling back to Bitstream Vera Sans
  (prop.get_family(), self.defaultFamily[fontext]))

I have the Humor Sans installed. I use archlinux and I installed the ttf-humor-sans package.

I have ensured that the font config cache fc-list finds the Humor Sans font:

$ fc-list | grep -i Humor
/usr/share/fonts/TTF/Humor-Sans-1.0.ttf: Humor Sans:style=Regular
grochmal
  • 2,901
  • 2
  • 22
  • 28
somenxavier
  • 1,206
  • 3
  • 20
  • 43

2 Answers2

3

Well, after properly looking at it, it is a kind of a bug. Using the following test:

import matplotlib.font_manager as fm
import matplotlib.pyplot as plt

font_cache = [i for i in
    fm.findSystemFonts(fontpaths=None, fontext='ttf')
    if 'umor' in i]
for i in font_cache:
    print(i)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1],[1],'o')
ax.set_title('My Title', fontname='Humor Sans')
#ax.set_title('My Title', fontname='Homemade Apple')
fig.savefig('tmp.png')

I have compared the behaviour of the Humor Sans against Homemade Apple (a free google font that i package into an AUR package). And the issue is that matplotlib does matching on the font names specified in fontname=, the matching does not use only the name but several properties of the font. in /home/grochmal/mat3/lib/python3.5/site-packages/matplotlib/font_manager.py you see the matching:

for font in fontlist:
    if (directory is not None and
        os.path.commonprefix([font.fname, directory]) != directory):
        continue
    # Matching family should have highest priority, so it is multiplied
    # by 10.0
    score = \
        self.score_family(prop.get_family(), font.name) * 10.0 + \
        self.score_style(prop.get_style(), font.style) + \
        self.score_variant(prop.get_variant(), font.variant) + \
        self.score_weight(prop.get_weight(), font.weight) + \
        self.score_stretch(prop.get_stretch(), font.stretch) + \
        self.score_size(prop.get_size(), font.size)
    if score < best_score:
         best_score = score
         best_font = font
    if score == 0:
         break

Unfortunately Humor Sans never reaches the matching phase because not all prop.get_... can be filled in. In essence it never gets included into fontlist. Homemade Apple is included because it can fill all the properties.

The difference in font properties can be seen as follows:

[me@haps aur]# otfinfo --info /usr/share/fonts/TTF/HomemadeApple.ttf
Family:              Homemade Apple
Subfamily:           Regular
Full name:           Homemade Apple
PostScript name:     HomemadeApple
Preferred family:    Homemade Apple
Preferred subfamily: Regular
Mac font menu name:  Homemade Apple
Version:             Version 1.000
Unique ID:           FontDiner,Inc: Homemade Apple: 2010
Description:         Copyright (c) 2010 by Font Diner, Inc. All rights reserved.
Designer:            Font Diner, Inc
Designer URL:        http://www.fontdiner.com
Manufacturer:        Font Diner, Inc
Vendor URL:          http://www.fontdiner.com
Trademark:           Homemade Apple is a trademark of Font Diner, Inc.
Copyright:           Copyright (c) 2010 by Font Diner, Inc. All rights reserved.
License URL:         http://www.apache.org/licenses/LICENSE-2.0
License Description: Licensed under the Apache License, Version 2.0
Vendor ID:           DINR

[me@haps aur]# otfinfo --info /usr/share/fonts/TTF/Humor-Sans-1.0.ttf
Family:              Humor Sans
Subfamily:           Regular
Full name:           Humor Sans
PostScript name:     HumorSans
Version:             Version 2.9 28/3/09
Unique ID:           Fontifier 2.9 (172) www.fontifier.com Humor Sans
Copyright:           Copyright (c) Randall Munroe's biggest fan 2009. Created by www.fontifier.com. usa-1lip-4fvu15
Vendor ID:           Alts

There missing fields from Humor Sans are not required, to be fair there are several inconsistencies in how fonts are described inside TTF (google italic vs. oblique for an example) therefore it isn't Humor Sans fault either. Your issue is a combination of inconsistencies in a file format with a lack of standardised code to deal with them.

I would suggest to find a different font that looks similar enough. Either editing the TTF or the matplotlib code is very tricky and might result in other problems.

grochmal
  • 2,901
  • 2
  • 22
  • 28
  • So, should we file a bug against humor sans package or against matplotlib package? Thanks for all your corrections and code. – somenxavier May 28 '16 at 13:53
  • I'd argue that both. Both are at fault to some extent: `matplotlib` for assuming too much from fonts and `Humor Sans` for not trying to be compatible as much as it can. Yet, i believe, this is the kind of bug that will not get fixed. Editing the matching code in `matplotlib` is too error prone, and font packages (`Humor Sans`) are often unmaintained (e.g. i package `Homemade Apple` but is do not own the font files, if that font presented such error i would be powerless). – grochmal May 30 '16 at 16:34
  • So what will we do for fixing this? – somenxavier Jun 01 '16 at 10:35
2

Humor Sans from the AUR works for me. However, I had to delete the font-cache first:
rm ~/.cache/matplotlib/fontlist-v330.json.

See https://stackoverflow.com/a/22812176

mauro3
  • 21
  • 1