Reputation: 121
Using matplotlib 2.2.2 with gridspec in Python 3.6.5, I created a huge plot for a research paper with several subplots. The axes objects are stored in a dictionary called axes
. This dictionary is passed to the function adjust_xticklabels()
, which is supposed to align the first xticklabel slightly to the right and the last xticklabel slightly to the left in each subplot, such that the xticklabels of neighbouring plots dont get in the way of each other. The function is defined as:
def adjust_xticklabels(axes, rate = 0.1):
for ax in axes.values():
left, right = ax.get_xlim() # get boundaries
dist = right-left # get distance
xtl = ax.get_xticklabels()
if len(xtl) > 1:
xtl[0].set_position((left + rate*dist, 0.)) # (x, y), shift right
xtl[-1].set_position((right - rate*dist, 0.)) # shift left
Calling it has no effect. Of course I also tried it with ridiculously high values. However, is has an effect in y-direction, for instance in case of setting xtl[0].set_position((0.3, 0.3))
.
A simple reproduction:
ax = plt.subplot(111)
ax.plot(np.arange(10))
xtl = ax.get_xticklabels()
xtl[4].set_position((0.3, 0.3)) # wlog, 4 corresponds to 6
I spent quite a while on trying to figure out if this is a feature or a bug. Did I miss something or is this a bug? Is there any other way to do the same thing?
Upvotes: 2
Views: 243
Reputation: 339102
This is a feature, no bug. The ticklabels are positionned at drawtime to sit at the correct locations according to the ticker in use. This ensures that the label always sits where the corresponding tick is located. If you change the limits, move or zoom the plot, the label always follows those changes.
You are usually not meant to change this location, but you may, by adding a custom transform to it. This is described in Moving matplotlib xticklabels by pixel value. The general idea is to set a translating transformation on the label. E.g. to translate the second label by 20 pixels to the right,
import matplotlib.transforms as mtrans
# ...
trans = mtrans.Affine2D().translate(20, 0)
label = ax.get_xticklabels()[1]
label.set_transform(label.get_transform()+trans)
Upvotes: 4