What knobs must I tweak to prevent these problems:
- overlapping axes labels
- overlapping plots with cropped axes labels
I'm using matplotlib 3.5.1 with the PGF backend. Some solutions for older versions no longer work.
fig, axes = plt.subplots\
(2, 3, constrained_layout=True, subplot_kw=dict(projection="3d"))
#it = np.nditer(axes, flags=["refs_ok","multi_index"])
#for ax in it:
# # Plot the surfaces, add row and column title annotations.
# pass
width = 150 * 0.8 * mm
height = width * 0.65
fig.set_size_inches(width, height)
fig.savefig("something.pgf", dpi=300)
plt.close(fig)
CodePudding user response:
Getting rid of the constrained layout and using plt.subplots_adjust(wspace=<value>, hspace=<value>)
worked for me
from matplotlib import pyplot as plt
fig, axes = plt.subplots(nrows=2, ncols=3, subplot_kw=dict(projection="3d"))
plt.subplots_adjust(wspace=0.5,hspace=0.5)
labels_x, labels_y, labels_z = [['x-axis']*3]*2, [['y-axis']*3]*2, [['z-axis']*3]*2
for i in range(len(axes)):
for j in range(len(axes[i])):
axes[i,j].set_xlabel(labels_x[i][j])
axes[i,j].set_ylabel(labels_y[i][j])
axes[i,j].set_zlabel(labels_z[i][j])
plt.show()
CodePudding user response:
While both tight and constrained layouts can be used with 3d projection (mplot3d) it seems that constrained layout does not understand how to pad 3d tick labels, leading to overlapping or trimmed labels. Both layout managers adjust subplot padding and axes size given a fixed figure size. Neither can fit the figure size to the contents. To do so with tight layout, extrapolate the desired figure size from the current figure tight bbox over multiple iterations. When using the constrained layout manager, sum the axes tight bboxes and padding to determine any extraneous space. Tight layout adjusts subplotpars (axes size and figure padding) and supports "h_pad" and "w_pad" parameters. Constrained layout adjusts axes size and supports "wspace", "hspace", "w_pad", and "h_pad" parameters. The tight layout squeezes subplots into a tight group which is then centered in the available space. The constrained layout distributes subplots evenly across all available space. Regardless of the layout manager, if the ticks overlap or are clustered too tightly, switch the tick locator to "MaxNLocator" for some smaller "n".
The root problem is that the 3d projection tick labels are empty until a full canvas draw. The "_draw_disabled" draw performed by the constrained layout manager isn't sufficient to trigger the tick labels. If you trace the axes tight bbox you'll notice they don't include the labels until after a call to "fig.canvas.draw", before then the tick labels are just "Text(0, 0, '')". Be sure to include this call after sizing the figure and then the layout will be constrained as expected. Given a fixed figure width, set the height based on aesthetics or sum the axes tight bboxes with padding to determine the minimum possible height.