Fonts and font families

Trying to understand the exact difference between fonts and font families. It appears to me, reading stuff online, that it is partially relative.

This documenation here has me somewhat confused. It referes to “sans-serif” as a font style, and “Tahoma” as a font family.

But then it sets rcParams[''] = 'sans-serif' and rcParams['font.sans-serif'] = ['Tahoma']

So which is the family? ‘sans-serif’ or ‘Tahoma’?

And if I look at rcparams that contain “font” as the first part of the rcparams key, I see (among others) the following:

KEY                   VALUE
font.cursive          [Apple Chancery, Textile, Zapf Chancery, Sand,...           [sans-serif]
font.fantasy          [Comic Neue, Comic Sans MS, Chicago, Charcoal,...
font.monospace        [DejaVu Sans Mono, Bitstream Vera Sans Mono, C...
font.sans-serif       [DejaVu Sans, Bitstream Vera Sans, Computer Mo...
font.serif            [DejaVu Serif, Bitstream Vera Serif, Computer ...

So if font.sans-serif is a family, what are DejaVu Sans, Bitstream Vera Sans, etc?

Aren’t they also families? Because, for example, within DejaVu I can see many individual fonts:


And if “DejaVu” is a family? What is “sans-serif”? And if “sans-serif” is not a family, then why is it the value of ??

Please explain if you can. Thank you.

Hi @DanielGoldfarb, the confusion is fairly understandable, let me try to explain:

The confusion is merely because of the use of phrase “font families”; there are actually two types of font family names:

  • “family-name”: choice of family name, for example, “Dejavu”, or “Tahoma”, etc.
  • “generic-family”: these are only 5: (‘serif’, ‘sans-serif’, ‘cursive’, ‘fantasy’ and ‘monospace’)

So to answer your first question, “sans-serif” and “Tahoma”, both are “font families”, however, “sans-serif” is a generic-family whereas “Tahoma” is an exact family-name.

The general consensus of how CSS or Matplotlib is supposed to work is:

  • User will provide us a list of “font families” (can contain family-name as well as generic-family)
  • A generic-family is encouraged to be appended to the font-family list as a last resort
  • If a user-defined family-name is not present in the system, we keep on iterating the family list to find a font-face that has required glyphs

Now here’s the fun part:
Even “generic-families” don’t just have a single font-face, they can be a combination of multiple “family-names”, i.e.,

KEY                   VALUE
font.sans-serif       [DejaVu Sans, Bitstream Vera Sans, Computer Mo...

So let’s imagine this scenario:

rcParams[''] = ['MyCustomFamily', 'sans-serif']
rcParams['font.sans-serif'] = ['Tahoma', 'DejaVu Sans']

So end of the day if you wanted us to render a character which wasn’t present in MyCustomFamily, as well as in Tahoma, we’ll end up using DejaVu Sans to render it, (and if even DejaVu Sans didn’t have a single font which has that particular glyph, we’d just render a “tofu”: )

The docs could be better on our side (is in our plans), but I hope this helped!