开发者

Adjust label positioning in Axes3D of matplotlib

开发者 https://www.devze.com 2023-02-21 09:25 出处:网络
I am having trouble with axes labels overlapping ticks labels in matplotlib. I\'ve tried to reposition the labels \"manually\" by applying transforms or by calling set_y(), but no avail.

I am having trouble with axes labels overlapping ticks labels in matplotlib. I've tried to reposition the labels "manually" by applying transforms or by calling set_y(), but no avail.

Here's a snippet that reproduces the problem:

import matplotlib
matplotlib.use("TKAGG")
import matplotlib.pyplot as pyplot
import mpl_toolkits.mplot3d

figure = pyplot.figure()
figure.subplots_adjust(bottom=0.25, top=0.75)
axes = figure.gca(projection='3d')
xLabel = axes.set_xlabel('XXX xxxxxx xxxx x xx x')
yLabel = axes.set_ylabel('YY (y) yyyyyy')
zLabel = axes.set_zlabel('Z zzzz zzz (z)')
plot = axes.plot([1,2,3],[1,2,3])

pyplot.show()

Note how the x and 开发者_StackOverflow中文版y labels clash with the ticks. Can I solve this elegantly ?


I share your frustration. I worked on it for a good half hour and got nowhere. The docs say set_xlabel takes an arg labelpad but I get an error (AttributeError: Unknown property labelpad)! Setting it after the fact doesn't do anything, on xaxis or w_xaxis.

Here's a crude workaround:

import matplotlib
matplotlib.use("TKAGG")
import matplotlib.pyplot as pyplot
import mpl_toolkits.mplot3d

figure = pyplot.figure(figsize=(8,4), facecolor='w')
ax = figure.gca(projection='3d')

xLabel = ax.set_xlabel('\nXXX xxxxxx xxxx x xx x', linespacing=3.2)
yLabel = ax.set_ylabel('\nYY (y) yyyyyy', linespacing=3.1)
zLabel = ax.set_zlabel('\nZ zzzz zzz (z)', linespacing=3.4)
plot = ax.plot([1,2,3],[1,2,3])
ax.dist = 10

pyplot.show()

Adjust label positioning in Axes3D of matplotlib


Add this for each axis, adapt the number:

axes.yaxis.labelpad=30

It is mentioned in the link by Adam Hughes as not working, but it works for me.


In new versions of matplotlib, this is how to do it:

ax.xaxis._axinfo['label']['space_factor'] = 2.8

See the explanation here:

https://github.com/matplotlib/matplotlib/issues/3610

Tested on v1.4, should work in versions > 1.1 I believe.


I really need to follow StackOverflow more often. I am the current maintainer of mplot3d. The reason why the various tricks that typically work in regular 2d plots don't work for 3d plots is because mplot3d was originally written up with hard-coded defaults. There were also bugs in how mplot3d calculated the angle to render the labels.

v1.1.0 contains several fixes to improve the state of things. I fixed the miscalculation of axes label angles, and I made some adjustments to the spacing. For the next release, I would like to have 3d axes to take up more than the default axes spacing, since the default was designed to take into account that tick labels and axes labels would be outside the axes, which is not the case for mplot3d. Because the spacings are determined by relative proportions in mplot3d, having a smaller space to work within forces the labels closer together.

As for other possible avenues for work-arounds, please see the note here. A fair warning, this private dictionary is not intended to be a permanent solution, but rather a necessary evil until the refactor of mplot3d is complete.

Also, v1.1.0 contains many updates to the api of mplot3d. Please check out the revised documentation here.


This changes the padding for all (x, y, z) labels in one shot. I like this approach the most:

from matplotlib import rcParams
rcParams['axes.labelpad'] = 20


As a design practice, transformed text is not very legible. I would suggest you to use labels for your axis, maybe color encoded. This is how you do it in matplotlib

import matplotlib
matplotlib.use("TKAGG")
import matplotlib.pyplot as pyplot
import mpl_toolkits.mplot3d

figure = pyplot.figure()
figure.subplots_adjust(bottom=0.25, top=0.75)
axes = figure.gca(projection='3d')
xLabel = axes.set_xlabel('X', fontsize=14, fontweight='bold', color='b')
yLabel = axes.set_ylabel('Y',fontsize=14, fontweight='bold', color='r')
zLabel = axes.set_zlabel('Z',fontsize=14, fontweight='bold', color='g')


x = pyplot.Rectangle((0, 0), 0.1, 0.1,fc='b')
y = pyplot.Rectangle((0, 0), 0.1, 0.1,fc='r')
z = pyplot.Rectangle((0, 0), 0.1, 0.1,fc='g')

handles, labels = axes.get_legend_handles_labels()
axes.legend((x,y,z),("XXXXXX","YYYYY","ZZZZZZ"),'best')


plot = axes.plot([1,2,3],[1,2,3])


pyplot.show()

Adjust label positioning in Axes3D of matplotlib


You can use labelpad after that you plot your figure:

axes = fig.gca(projection='3d')
axes.xaxis.labelpad=20
axes.yaxis.labelpad=20
axes.zaxis.labelpad=20

This might cause the axis labels to go outside the 3D plot so you have to adjust the distance using the dist method:

ax.dist = 13


I'm using mpl 3.4.3 and I am still having this issue. I should note I am using 3D subplots, perhaps that is my issue?

fig = plt.figure(figsize=(3,2))
ax = fig.add_subplot(1,2,i,projection='3d')

I feel like I have tried everything, including answers here. I just cannot get my tick labels or axis label where I want it.

Without touching the padding I have (note the zaxis label for the left plot is off the fig):

Adjust label positioning in Axes3D of matplotlib

The following pushes the labels quite far away, as expected:

ax.xaxis.labelpad = 20
ax.yaxis.labelpad = 20
ax.zaxis.labelpad = 20

Adjust label positioning in Axes3D of matplotlib

So I figure reducing those numbers should bring them closer. The following brings the yaxis (realizations) quite close to the tick labels, but not xaxis and zaxis labels:

ax.xaxis.labelpad = 1
ax.yaxis.labelpad = 1
ax.zaxis.labelpad = 1

Adjust label positioning in Axes3D of matplotlib

Tweaking a bit harder on xaxis and zaxis doesn't do anything:

ax.xaxis.labelpad = 0.1
ax.yaxis.labelpad = 1
ax.zaxis.labelpad = 0.001

Adjust label positioning in Axes3D of matplotlib

Sorry this isn't an answer, but I feel like the adjustments I present here and the unexpected behavior may help stimulate an appropriate answer?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号