Skip to content

Feature request: set mathtext fonts via the object oriented API #6518

Closed

Description

@ngoldbaum

As far as I can see (and according to the documentation), the only way to set the font of mathtext snippets in plots is via the mathtext.fontset rcparam.

It would be nice if there were some way to control the fonts used for mathtext rendering without messing with the rcparams system. Maybe the font could be chosen based on the FontProperties instance associated with the Text object? To make a concrete example, it would be nice if the y label for this plot were rendered using a serif font, like the rest of the plot.

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties

fig, ax = plt.subplots()

fp = FontProperties(**{'family': 'stixgeneral'})

im = ax.imshow(np.random.random((800, 800)))
cb = fig.colorbar(im)
cbax = cb.ax

ax.set_xlabel('x label')
ax.set_ylabel(r'$\rm{y\ label}$')
cb.set_label('colorbar label')

labels = ax.xaxis.get_ticklabels() + ax.yaxis.get_ticklabels()
labels += cbax.yaxis.get_ticklabels()
labels += [ax.xaxis.label, ax.yaxis.label, cbax.yaxis.label]

for label in labels:
    label.set_fontproperties(fp)

plt.savefig('test.png')

For additional context, see #6514 and my message to the matplotlib-devel mailing list: https://mail.python.org/pipermail/matplotlib-devel/2016-May/000454.html

Activity

  1. zblz commented on Jun 1, 2016

    @zblz
    Member

    Can this be achieved with an rc_context withouth touching user rcparams?

    with mpl.rc_context(rc={'mathtext.fontset':'stix'}):
        fig, ax = ....
    

    I agree it would be nice for a way to set both text and mathtext fonts as a group so they are consistent, and currently it is not completely obvious.with mpl.rc_context(fname='mpl.rc', rc={'text.usetex': True}):

    edit: nevermind, I saw you already mentioned the context manager in the email.

  2. ngoldbaum commented on Jun 1, 2016

    @ngoldbaum
    ContributorAuthor

    While it's true that this issue can be dealt with using a context manager (ping @mdboom and @WeatherGod, let's move discussion to this issue since it has a clearer call for action), I think that's less useful than being able to programmatically customize fonts using the FontProperties interface. Keep in mind that I'm thinking in the context of yt, which has a several thousand line wrapper around matplotlib, so saying "use the context manager" is more complex for me since the plotting code is spread out over several modules (since I make use of inheritance to avoid code duplication) and many different functions.

    Here's a couple reasons to justify why I want something besides the context manager approach:

    1. It provides a uniform interface for setting fonts for all text.
    2. I might not know that the text being displayed by a given Text object (for example, a label in a plot) is MathText or regular text - so I need to implement two very different code paths, one that sets an RC param as the plot is drawn, another that sets the FontProperties at some point before the plot is drawn, just to ensure that the two kinds of text have consistent fonts.
    3. This isn't isolated to axis and colorbar labels, since the tick marks for axes that have logarithmic scales are rendered in MathText by default, so I also need to have special handling for tick label fonts as well.
    4. It violates the principle of least surprise to silently ignore the font settings from the FontParameters associated with a text object, just because the text being displayed contains a MathText expression.
  3. mdboom commented on Jun 1, 2016

    @mdboom
    Member

    The tricky bit here is that math rendering requires a particular set of fonts that work together (the "fontset") rather than a single font. There are only a very small set of such fontsets supported. So we'd need to add a new property to FontProperty to set the fontset and ignore all others. Not really an ideal API either.

  4. ngoldbaum commented on Jun 1, 2016

    @ngoldbaum
    ContributorAuthor

    That actually sounds nice to me - I could do:

    fp = FontProperties(**{'family': 'stixgeneral', 'mathtext-fontset': 'cmr'})

    And non-mathtext text will use 'stixgeneral', while mathtext uses computer modern.

  5. WeatherGod commented on Jun 1, 2016

    @WeatherGod
    Member

    I'll be +1 to that idea, but I get the point that it isn't ideal. As a
    user, I say "use this font", and that font doesn't get used... I would be
    rather surprised. It isn't immediately obvious that I would need to specify
    two parameters to set my fonts. The font-handling system is probably due
    for an overhaul soon, I think.

    On Wed, Jun 1, 2016 at 1:28 PM, ngoldbaum notifications@github.com wrote:

    That actually sounds nice to me - I could do:

    fp = FontProperties(**{'family': 'stixgeneral', 'mathtext-fontset': 'cmr'})

    And non-mathtext text will use 'stixgeneral', while mathtext uses computer
    modern.

    —
    You are receiving this because you were mentioned.
    Reply to this email directly, view it on GitHub
    #6518 (comment),
    or mute the thread
    https://github.com/notifications/unsubscribe/AARy-Gw71bwVW_EovpiUCqBflrAdhkB6ks5qHcFYgaJpZM4IrIqG
    .

  6. zblz commented on Jun 2, 2016

    @zblz
    Member

    A possible alternative would be to set mathtext.fontset by default to None, and write some logic that selects the fontset depending on the FontProperties of the surrounding text, trying to get as good a match as possible. If mathtext.fontset is specified, then we go with that no matter the FontProperties. I imagine that this would be closer to most user's expected behaviour.

    However, in the case specified by @ngoldbaum ('family': 'stixgeneral') the fontset chosen would probably have to be stix rather than cmr...

  7. efiring commented on Jun 2, 2016

    @efiring
    Member

    On 2016/06/01 10:51 PM, Victor Zabalza wrote:

    A possible alternative would be to set |mathtext.fontset| by default to
    None, and write some logic that selects the fontset depending on the
    FontProperties of the surrounding text, trying to get as good a match as
    possible.

    Looking at surrounding text? That sounds much too complicated and magical.

  8. added this to the milestone on Jun 3, 2016
  9. modified the milestones: , on Jul 16, 2016
  10. modified the milestones: , on Oct 3, 2017
  11. anntzer commented on May 23, 2021

    @anntzer
    Contributor

    Closed by #18145.

  12. modified the milestones: needs sorting, v3.4.0 on May 23, 2021
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