可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 y labels clash with the ticks. Can I solve this elegantly ?
回答1:
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()
回答2:
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.
回答3:
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.
回答4:
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.
回答5:
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
回答6:
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()