Skip to content

Vertical alignment of tick labels with usetex=True #6323

Closed

Description

@KeithWM

If I set

plt.rc('text', usetex=True)

the vertical alignment of tick labels is incorrect. For negative ticks, the tick labels are quite visibly lower than the positive marks. See the screenshot for an example.

A minimal working example:
from matplotlib import pyplot as plt
plt.close('all')
# import seaborn as sns
# sns.set_context("poster", font_scale=2)

fig = plt.figure()
plt.rc('text', usetex=False)
ax = fig.add_subplot(1,2,1)
plt.plot((-7.,0.,7.), (-1.,0.,1.), 'r-')
plt.rc('text', usetex=True)
ax = fig.add_subplot(1,2,2)
plt.plot((-7.,0.,7.), (-1.,0.,1.), 'r-')

plt.show()

screen shot 2016-04-21 at 12 42 30 1

The screenshot uses seaborn, as using its font properties exaggerates the error, but it is also visible without seaborn on close inspection.

In constructing this MWE, I discovered that the problem goes away if I reverse the order of the two plots, or if I set plt.rc('text', usetex=False) before plt.show().

I installed python 2.7.11 and matplotlib 1.5.1 via anaconda. I'm using the Qt4Agg backend, interactively.

Activity

  1. WeatherGod commented on Apr 21, 2016

    @WeatherGod
    Member

    attn: @mdboom. I am a bit disconcerted that the 2 and 4 (positive and
    negative) in the left panel isn't lined up right, either, I think.

    On Thu, Apr 21, 2016 at 6:48 AM, KeithWM notifications@github.com wrote:

    If I set

    plt.rc('text', usetex=True)

    the vertical alignment of tick labels is incorrect. For negative ticks,
    the tick labels are quite visibly lower than the positive marks. See the
    screenshot for an example.

    A minimal working example:
    from matplotlib import pyplot as plt
    plt.close('all')

    import seaborn as sns

    sns.set_context("poster", font_scale=2)

    fig = plt.figure()
    plt.rc('text', usetex=False)
    ax = fig.add_subplot(1,2,1)
    plt.plot((-7.,0.,7.), (-1.,0.,1.), 'r-')
    plt.rc('text', usetex=True)
    ax = fig.add_subplot(1,2,2)
    plt.plot((-7.,0.,7.), (-1.,0.,1.), 'r-')

    plt.show()

    [image: screen shot 2016-04-21 at 12 42 30 1]
    https://cloud.githubusercontent.com/assets/11614277/14706405/9c7f8e16-07be-11e6-9628-87267de8d234.png

    The screenshot uses seaborn, as using its font properties exaggerates the
    error, but it is also visible without seaborn on close inspection.

    In constructing this MWE, I discovered that the problem goes away if I
    reverse the order of the two plots, or if I set plt.rc('text',
    usetex=False) before plt.show().

    I installed python 2.7.11 and matplotlib 1.5.1 via anaconda. I'm using the
    Qt4Agg backend, interactively.

    —
    You are receiving this because you are subscribed to this thread.
    Reply to this email directly or view it on GitHub
    #6323

  2. self-assigned this
    on Apr 25, 2016
  3. mdboom commented on Apr 25, 2016

    @mdboom
    Member

    TeX is returning bogus descender values for the negative sign. Haven't quite figured out why yet.

  4. added a commit that references this issue on Apr 25, 2016
    c7848de
  5. Kojoley commented on Jan 4, 2017

    @Kojoley
    Member

    It is still the case
    image

  6. aseyffert commented on Jan 28, 2020

    @aseyffert

    A temporary workaround is to use LaTeX's \phantom{} command; e.g, for a plot with xticks at [-2, -1, 0, 1, 2] you can manually set the xticklabels as:

    ax.set_xticklabels([r'$-2$', r'$-1$', r'$\phantom{-}0\phantom{-}$', r'$\phantom{-}1\phantom{-}$', r'$\phantom{-}2\phantom{-}$'])

    This causes LaTeX to affect a vertical shift in the positive labels as well (this is therefore not a fix but a workaround). The trailing \phantom{} calls are necessary to maintain the horizontal alignment of the tick labels.

  7. anntzer commented on Jan 29, 2020

    @anntzer
    Contributor

    I looked a bit into this and as it turns out it is intentionally that the minus sign has a nonzero descent: https://tex.stackexchange.com/questions/526103/why-does-cmsy10-tfm-give-the-minus-sign-a-positive-depth/ (thanks tex.stackexchange). Essentially, the tfm metrics are used (especially) to alignment of math formulae, rather than to determine rasterization bboxes, which is what we need here.

    There are a few solutions here:

    • Use mplcairo's approach, which is to not use dvipng at all for conversion but instead extract the glyphs one by one from the dvi file and re-render them using ft2font (we already have code to do that for the pdf/ps backends).
    • Instead of relying on the tfm metrics, use the pfb font which pdftex.map points to (the mapping is documented as "the most prominent use of pdftex.map" by the pdftex user manual), and extract the metrics from it.
    • Special-case the minus glyph as per Fix #6323: Fix vertical alignment of TeX text #6333, which is vaguely unsatisfying but perhaps the simplest.

    The advantage of the first two solutions is that (I think) this would allow us to get rid of the Tfm and possibly Vf classes, as we would be able to rely on freetype to get glyph metrics.

  8. added this to the v3.3.0 milestone on Feb 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions