Skip to content

Tick label alignment not working as described #13440

Closed

Description

@oestfeldt

Bug report

Bug summary

I want to change the horizontal alignment of the tick labels on my y-axis. This page explains a method (the one-liner on the top of the page), which does not work.

Code for reproduction

import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
print("Matplitlib version: %s" % mpl.__version__)
 
x = np.logspace(-2,3)
y = 1 / (exp(1/x) - 1)

fig = plt.figure(1, figsize=(4, 4))
plt.loglog(x,y)
plt.xlabel('x')
plt.ylabel('y')
plt.tight_layout()

ax = plt.gca()
ax.yaxis.set_tick_params(horizontalalignment='left')

The code above is slightly longer than minimum, to motivate why I need to change the tick label alignment. The changing size of the exponent looks ugly when the labels are right-aligned.

Actual outcome

axislabelcentertest

Matplitlib version: 3.0.2
Traceback (most recent call last):

  File "<ipython-input-17-ff49df94c4af>", line 1, in <module>
    runfile('/home/christoffer/Dropbox/Div/axislabelcentertest.py', wdir='/home/christoffer/Dropbox/Div')

  File "/home/christoffer/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 668, in runfile
    execfile(filename, namespace)

  File "/home/christoffer/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 108, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "/home/christoffer/Dropbox/Div/axislabelcentertest.py", line 16, in <module>
    ax.yaxis.set_tick_params(horizontalalignment='left')

  File "/home/christoffer/anaconda3/lib/python3.7/site-packages/matplotlib/axis.py", line 852, in set_tick_params
    kwtrans = self._translate_tick_kw(kw, to_init_kw=True)

  File "/home/christoffer/anaconda3/lib/python3.7/site-packages/matplotlib/axis.py", line 917, in _translate_tick_kw
    % (key, kwkeys))

ValueError: keyword horizontalalignment is not recognized; valid keywords are ['size', 'width', 'color', 'tickdir', 'pad', 'labelsize', 'labelcolor', 'zorder', 'gridOn', 'tick1On', 'tick2On', 'label1On', 'label2On', 'length', 'direction', 'left', 'bottom', 'right', 'top', 'labelleft', 'labelbottom', 'labelright', 'labeltop', 'labelrotation', 'grid_agg_filter', 'grid_alpha', 'grid_animated', 'grid_antialiased', 'grid_clip_box', 'grid_clip_on', 'grid_clip_path', 'grid_color', 'grid_contains', 'grid_dash_capstyle', 'grid_dash_joinstyle', 'grid_dashes', 'grid_drawstyle', 'grid_figure', 'grid_fillstyle', 'grid_gid', 'grid_in_layout', 'grid_label', 'grid_linestyle', 'grid_linewidth', 'grid_marker', 'grid_markeredgecolor', 'grid_markeredgewidth', 'grid_markerfacecolor', 'grid_markerfacecoloralt', 'grid_markersize', 'grid_markevery', 'grid_path_effects', 'grid_picker', 'grid_pickradius', 'grid_rasterized', 'grid_sketch_params', 'grid_snap', 'grid_solid_capstyle', 'grid_solid_joinstyle', 'grid_transform', 'grid_url', 'grid_visible', 'grid_xdata', 'grid_ydata', 'grid_zorder', 'grid_aa', 'grid_c', 'grid_ls', 'grid_lw', 'grid_mec', 'grid_mew', 'grid_mfc', 'grid_mfcalt', 'grid_ms', 'grid_aa', 'grid_c', 'grid_ls', 'grid_lw', 'grid_mec', 'grid_mew', 'grid_mfc', 'grid_mfcalt', 'grid_ms']

Expected outcome

I expect the alignment of the y-axis tick labels to change.

Matplotlib version

  • Operating system: Ubuntu 18.04
  • Matplotlib version: 3.0.2
  • Matplotlib backend (print(matplotlib.get_backend())): Qt5Agg
  • Python version: 3.7.1
  • Jupyter version (if applicable):
  • Other libraries: Numpy

Installed via conda.

Activity

  1. timhoffm commented on Mar 3, 2019

    @timhoffm
    Member

    This is a two part issue:

    1. The documentation was wrong Revert invalid change in Centered Ticklabels example #13578.

    2. Even when setting the alignment for each tick individually, you won't get what you are expecting. The alignment takes place with respect to a reference point. Therefore

    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib as mpl
    print("Matplitlib version: %s" % mpl.__version__)
     
    x = np.logspace(-2,3)
    y = 1 / (np.exp(1/x) - 1)
    
    fig = plt.figure(1, figsize=(4, 4))
    plt.loglog(x,y)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.tight_layout()
    
    ax = plt.gca()
    
    for label in ax.yaxis.get_ticklabels():
        label.set_horizontalalignment('left')
    

    will result in

    image

  2. oestfeldt commented on Mar 4, 2019

    @oestfeldt
    Author

    Ok, thanks a lot.

    @1
    Well, this is of course a perfectly valid answer :) Unless I am mistaken, the page that I linked to still lists this solution as valid?

    @2
    Ok, thanks. While I realize that this is maybe not the ideal place to state this, I think that adding alignment of ticks is a worthwhile addition to matplotlib.

    If anyone knows a hotfix, I'd be happy to know.

  3. timhoffm commented on Mar 5, 2019

    @timhoffm
    Member

    @1
    You've linked the docs of the current stable release. They will only get updated on the next release. The current development docs are here https://matplotlib.org/devdocs/gallery/ticks_and_spines/centered_ticklabels.html

    @2
    May be a bit tricky because the alignment would have to be a common operation depending on the size of all other labels. Until now the parameters are just handed through to each label. This would probably need an internal 2-pass approach (e.g. if fontsize is given simultaneously, that would have to be applied first to determine how wide the labels are and have to be moved.).

    As a workaround, you can do

    ax.yaxis.set_tick_params(pad=32)
    

    or if you don't want to tune with hard-coded numbers

    width = max(label.get_window_extent(fig.canvas.renderer).width for label in ax.yaxis.get_ticklabels())
    ax.yaxis.set_tick_params(pad=width+2)
    
  4. added
    Difficulty: Hardhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issues
    on Mar 22, 2019
  5. anntzer commented on Mar 22, 2019

    @anntzer
    Contributor

    Labeling as hard (borderline wontfix, I'd say) because making all y labels talk to each other to achieve proper left-alignment would require quite a bit of work, I think.

  6. timhoffm commented on Mar 23, 2019

    @timhoffm
    Member

    This might be handled best via a TextCollection class as proposed in #4063.

  7. stevenlis commented on Sep 14, 2020

    @stevenlis

    @timhoffm it seems like the issue has been fixed with 3.3.1

  8. tacaswell commented on Sep 15, 2020

    @tacaswell
    Member

    I think the docs have been fixed from 3.1.1 (looking at the milestone on that PR), but I think that @timhoffm suggestion to render the figure once to get the text sizes and then shift the padding out is the only reliable way to do this currently.

  9. github-actions commented on Jun 1, 2023

    @github-actions

    This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

  10. tacaswell commented on Jun 2, 2023

    @tacaswell
    Member

    The docs are fixed and even though it is annoying, the behavior from #13440 (comment) for setting the left alignment is the correct and expected behavior. You can adjust the pad on the tick labels to push them out.

    If you are willing to use axisartist this is supported:
    https://matplotlib.org/stable/gallery/axisartist/demo_ticklabel_alignment.html

    I am going to close this as resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Difficulty: Hardhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issuesstatus: inactiveMarked by the “Stale” Github Action

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions