Skip to content

Tick label alignment not working as described #13440

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
oestfeldt opened this issue Feb 15, 2019 · 9 comments
Closed

Tick label alignment not working as described #13440

oestfeldt opened this issue Feb 15, 2019 · 9 comments
Labels
Difficulty: Hard https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues status: inactive Marked by the “Stale” Github Action

Comments

@oestfeldt
Copy link

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.

@timhoffm
Copy link
Member

timhoffm commented Mar 3, 2019

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

@oestfeldt
Copy link
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.

@timhoffm
Copy link
Member

timhoffm commented Mar 5, 2019

@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)

@anntzer anntzer added the Difficulty: Hard https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues label Mar 22, 2019
@anntzer
Copy link
Contributor

anntzer commented Mar 22, 2019

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.

@timhoffm
Copy link
Member

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

@stevenlis
Copy link

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

@tacaswell
Copy link
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.

@github-actions
Copy link

github-actions bot commented Jun 1, 2023

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!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label Jun 1, 2023
@tacaswell
Copy link
Member

tacaswell commented Jun 2, 2023

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
Labels
Difficulty: Hard https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues status: inactive Marked by the “Stale” Github Action
Projects
None yet
Development

No branches or pull requests

5 participants