1

I have a variety of fonts installed on my system (OS X 10.9.1), and am able to use them all with no problems in all of my tools and applications (including my LaTeX installation) but my attempts to specify a specific font in matplotlib (with text.usetex=False) produce unexpected and confusing results.

For example

font = {'family': 'sans-serif', 
        'sans-serif': ['Open Sans', 'Avenir', 'sans-serif']}
plt.rc('font', **font)

results in neither Open Sans nor Avenir being used, though specifying a size (e.g., 'size': 20) changes the size as expected.

Strangely, specifying a weight not only changes the weight, but can also result in the font changing. For example

font = {'family': 'sans-serif', 
        'sans-serif': ['Open Sans', 'Avenir', 'sans-serif'],
        'weight': 'bold'}
plt.rc('font', **font)

seems to result in Open Sans being used (but as something that looks like extra-bold rather than bold). If I make weight 550 or more I get the same effect; while anythng less results in the wrong font. I get similar odd behavior with other fonts (e.g.. Sika or Gill Sans), and see this regardless of of whether the font is OT, TT, or whether it is indicated as a System or User font.

Why is (only) matplotlib responding in this strange way. Are there matplotlib (or Python) settings or configuration options I should be changing to ensure that I get the expected behavior? Is there some other way I should be specifying the font weight, perhaps?


FWIW, here's how Open Sans looks in my font installation:

enter image description here

All of these are found by Python as expected (in /Users/Rax/Library/Fonts/) by

import matplotlib.font_manager
print matplotlib.font_manager.findSystemFonts(fontpaths=None)

and

font_manager.FontProperties(fname='/Users/Rax/Library/Fonts/OpenSans-ExtraBold.ttf').get_name()
font_manager.FontProperties(fname='/Users/Rax/Library/Fonts/OpenSans-Regular.ttf').get_name()

both report 'Open Sans' as the font name, as expected, with

font_manager.FontProperties(fname='/Users/Rax/Library/Fonts/OpenSans-Regular.ttf').get_weight()

reporting 'normal'.

orome
  • 45,163
  • 57
  • 202
  • 418
  • As I dig deeper, this starting to look like several distinct questions; I may ask each separately. (And possibly close this one.) – orome Dec 22 '13 at 17:19

1 Answers1

0

If you don't have one already, you might want to set up a matplotlibrc file and see if those settings stick. Put it in ~/.matplotlib/matplotlibrc and it'll be read automatically upon startup. I haven't customized mine for fonts yet, but when I altered some other settings in it (image DPI, specifically) it was picked up when I restarted IPython with pylab, so hopefully it'll work for you.

MattDMo
  • 100,794
  • 21
  • 241
  • 231
  • Can you elaborate on how that will help? – orome Dec 21 '13 at 20:50
  • Well, I was thinking if you set `font.sans-serif : Open Sans, Avenir, sans-serif` it may result in the behavior you were trying to achieve in `plt.rc('font', **font)` without additionally setting the weight option. – MattDMo Dec 21 '13 at 20:58
  • Is there a way to test what font file has been loaded by my code; or perhaps to force a specific font file to load? – orome Dec 21 '13 at 21:53
  • check out the [`FontProperties`](http://matplotlib.org/api/font_manager_api.html#matplotlib.font_manager.FontProperties) class of `matplotlib.font_manager` - it has `get_file()` and `get_name()` methods that may be useful. – MattDMo Dec 21 '13 at 22:07
  • How do I identify the current font to apply these methods to? All files in the list returned by `findSystemFonts` with 'OpenSans-' in their names have font names 'Open Sans', and all fonts named 'Open Sans' have files names that begin with 'OpenSans-'. – orome Dec 22 '13 at 03:07
  • As I dig deeper into this, it's starting to look like several distinct questions; I may ask each separately. (And possibly close this one.) – orome Dec 22 '13 at 17:18