Skip to content

Tick label positioning only works orthogonal to axis #7112

Closed as not planned
Closed as not planned

Description

@FaustinCarter

matplotlib v1.5.1, build np111py27_0, via Anaconda
Python 2.7 via Anaconda
OSX

Attempting to fine tune the positioning of the tick labels only works orthogonal to the direction of the axis in question. It is desirable to shift the ticks along their parent axis sometimes when the left/right/center alignment doesn't produce nice results (i.e. very long tick labels that have been rotated).

I assume that the parallel shift is overwritten at render time? Below is an example of the behavior, and also an example of how it should (I think) work using a monkey patch.

Example:

#Imports
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import types

#Make a figure and plot something that gives
#different ticks on each axis (so as to tell
#them apart)
f = plt.figure(figsize=(5,5))

x = np.linspace(0, 10)
y = 10*x

ax = f.add_subplot(111)
ax.plot(x,y)

#An arbitrary small shift (in coords where
# left/down = 0 and right/up = 1)
shift = 0.125

#Grab the 3rd and 5th tick from each axis
x_tick_3 = ax.xaxis.get_majorticklabels()[2]
y_tick_3 = ax.yaxis.get_majorticklabels()[2]

x_tick_5 = ax.xaxis.get_majorticklabels()[4]
y_tick_5 = ax.yaxis.get_majorticklabels()[4]

#Try and shift the 3rd tick from each axis
#Only shifts in orthogonal direction, ignores
#attempt at parallel shifting

#The "4" tick gets moved up, but not right
x_tick_3.set_x(shift) #<-- does nothing
x_tick_3.set_y(shift) #<-- works great

#The "40" tick gets moved right, but not up
y_tick_3.set_x(shift) #<-- works great
y_tick_3.set_y(shift) #<-- does nothing

#Monkey patch the set_x and set_y methods for
#the 5th ticks and move them

#The "8" tick now gets moved right and up
x_tick_5.custom_shift = shift*(10-1) #<-- convert to xaxis coords (domain-dx)
x_tick_5.set_x = types.MethodType(lambda self, x: mpl.text.Text.set_x(self, x+self.custom_shift), 
                                x_tick_5, mpl.text.Text) #<-- now gets shifted
x_tick_5.set_y(shift) #<-- still works

#The "80" tick now gets moved right and up
y_tick_5.custom_shift = shift*(100-10) #<-- convert to yaxis coords (range-dy)
y_tick_5.set_y = types.MethodType(lambda self, y: mpl.text.Text.set_y(self, y+self.custom_shift), 
                                y_tick_5, mpl.text.Text) #<-- now gets shifted
y_tick_5.set_x(shift) #<-- still works

issue_demo

Activity

  1. added this to the milestone on Sep 15, 2016
  2. tacaswell commented on Sep 24, 2017

    @tacaswell
    Member

    I am not convinced that this is a bug (we put the ticks where they should be parallel to the axes) and the way that the ticks are currently handled makes implementing this extremely hard (the instances get reused by shifting them and changing the text).

  3. FaustinCarter commented on Sep 25, 2017

    @FaustinCarter
    Author

    This is definitely a bug because the auto-positioning for very long tick labels that are rotated is absolutely not correct and requires hand tuning!

  4. tacaswell commented on Sep 25, 2017

    @tacaswell
    Member

    Can you provide an example? That sounds like the ticks are placed badly, not that we need a way to hand-tune their position.

  5. modified the milestones: , on Sep 25, 2017
  6. jklymak commented on Sep 25, 2017

    @jklymak
    Member

    I think the script above shows the “bug” adequately. However I’m not volunteering to fix it :-)

  7. FaustinCarter commented on Sep 25, 2017

    @FaustinCarter
    Author

    OK, so I drummed up two figures that illustrate the point. The issue really shows up when you have really long tick labels in a subplot right next to an axis with really short tick labels. You have to rotate the long tick labels to display them, which then forces the choice of alignment. Aligning the labels to the center will bleed the really long labels into the labels for the shorter plot, so one has to use x_tick_label.set_horizontalalginment('right') and y_tick_label.set_verticalalginment('top'). This comes close to fixing it, but it still doesn't quite get it right, as the angled labels point towards the tick rather than actually being right/top aligned with the tick. The solution is to either make right/top alignment align to the center of the last digit in the tick label, or to allow more fine grained control of the placement parallel to the axis so folks can do it how they like.

    This image has no shift applied. I just right-aligned the x-axes and top-aligned the y-axes after rotating the labels.

    noshift

    This image has had the shifts applied. After aligning, I manually applied a shift via the monkey-patching method outlined in the top post. I think this is a preferable outcome.

    withshift

    This example is not entirely contrived either. When trying to display the parameter covariances in a model with many different fit parameters, this huge mismatch between number of significant digits between parameters can arise easily.

  8. tacaswell commented on Sep 26, 2017

    @tacaswell
    Member

    Wouldn't those cases be better handled by an offset text? Might also be more readable to only rotate the x tick labels to 90deg. Have you tried adjusting the tick pad?

    I am however convinced that this is a reasonable feature to want.

  9. tacaswell commented on Sep 26, 2017

    @tacaswell
    Member

    Probably should be implemented as a opad in points or em.

  10. modified the milestones: , on Sep 26, 2017
  11. github-actions commented on Mar 29, 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!

  12. added
    status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.
    on May 30, 2023
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

    New featurestatus: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.status: inactiveMarked by the “Stale” Github Actiontopic: text

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions