Skip to content

macosx backend doesn't find fonts the same way as other backends #781

Closed

Description

@zpincus

All of the other backends appear to use matplotlib.font_manager.findfont() to look up the path for a given font file to use. However, the macosx backend has its own font-lookup mechanism: src/_macosx.m line 2256, setfont().

This mechanism is essentially an odd way to look up the pre-defined PS fonts, and in particular:

  1. looks only at the font-family name, and does not defer to font-family preference lists from rcParams, such as "font.sans-serif" etc.
  2. does not take any properties into account except for a weight that is exactly "bold" or a variant that is exactly "italic".

It is possible to get this font-lookup to find an arbitrary font by passing a PS-style name such as "MyriadPro-Semibold" as the font-family, but this doesn't work for other backends. (findfont() requires the semibold to be passed in as a weight property, not the family name, even though the eventual file returned is named "MyriadPro-Semibold.otf")

There are several possible solutions; I'm not sure which is best:

  1. make findfont() look up fonts by fully-qualified name such as "MyriadPro-Semibold", so that this style could be used for all backends.
  2. make a function to return a compatible name for a given font found by findfont(). Perhaps this would just be the filename (sans extension) from the path returned by findfont?
  3. fix src/_macosx.m:setfont() to load a font from a path passed in. I get the feeling that this isn't exactly the "encouraged" way to deal with fonts on OS X though...

The downside of using findfont(), and why I presume the macosx backend doesn't, is that FreeType2 (and thus findfont()) can't deal with dfont and other font suitcase types, which can be easily loaded by the cocoa font-lookup routines in _macosx.m. But using such fonts results in the case where one can display a plot on OS X, but saving it creates an error.

Any thoughts? Would it be better to funnel things through findfont() for consistency, at the cost of not being able to use some of the basic fonts on OS X (Helvetica, Courier, etc., are all dfonts -- but hence couldn't be used for figure-saving anyway)? That's option 2 or 3. Or better to leave OS X as it is, and just let other backends look up available fonts by filename too? (Option 1)

Activity

  1. iMichka commented on May 22, 2013

    @iMichka
    Contributor

    Hi

    I would like to know if there is any plan to get this issue solved ? It's quite annoying when you embed matploltib in a GUI on OS X and you can't use the systems default font which is Helvetica (I use PyQT, so now I have a nice GUI, but with Bitstream Vera Sans plots in it ...). And if you have plots to exports as .eps, you have to reopen them in another software to change all the fonts to the one you want. Not very effective ...

    I could help do the tests or write some code but I think this implies a lot of work/changes in matplotlib. There seem also to be many ways to solve this problem ?

    Or perhaps is there a hack or trick to enable Helvetica in matplotlib under OS X ?

  2. pelson commented on May 22, 2013

    @pelson
    Member

    Hi @iMichka - sounds like you're not using the macos backend, which I'm pretty sure this issue is about. The matplotlib fonts capabilities for Agg based backends is quite comprehensive, though I think it is severely lacking in documentation. If you know the path of your Helvetica.ttf you might be able to use the answer at http://stackoverflow.com/questions/7726852/how-to-use-a-random-otf-or-ttf-font-in-matplotlib .
    The harder to follow docs can be found: http://matplotlib.org/api/font_manager_api.html .

    I'd advise the best place to get help on this would be the matplotlib-users mailinglist.

    HTH

  3. iMichka commented on May 23, 2013

    @iMichka
    Contributor

    I tried to set manually the font with your hint from stackoverflow, and it worked ! (Did not know previously about this). It worked with MacOSX and Qt4Agg backend. I had to use fondu to convert my Helvetica .dfont to .ttf, which was quite complicated ...

    So this would be a solution but it has 2 disadvantages

    • I have to manually set fontproperties everywhere in my code (for labels, titles, axes, annotations, ....)
    • I'll have to ship Helvetica with my app, which is not allowed due to copyright ? (Seems it's not a free font ...). I can't ask my users to go through the fondu process.

    I hoped for an easy out-of the box solution like :
    matplotlib.rcParams['font.family'] = 'Helvetica'

    But this won't work on OS X. So as I saw this issue to rewrite the font loading mechanism for OS X I hoped a solution was under way. I posted here to get an update on the situation.

    I should continue the discussion on the matplotlib-users mailinglist then. Or I'll look for a free alternative to Helvetica.

  4. mdboom commented on May 23, 2013

    @mdboom
    Member

    Thanks -- I keep meaning to write a text-handling MEP that would address all of the different text backends we have and try to create some rhyme or reason to them (which is hard, because the semantics are different on every platform, with TeX and matplotlib's native text handling another "platform" unto themselves). Something to get to when I have time... ;)

  5. added this to the milestone on Aug 18, 2014
  6. mdboom commented on Mar 21, 2016

    @mdboom
    Member

    Fixed by #6178

  7. modified the milestones: , on Mar 28, 2016
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