I have some code which produces a 3D scatter plot using matplotlib's scatter
in conjunction with tight_layout
, see the simplified code below:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import proj3d
fig = plt.figure()
ax = fig.gca(projection='3d')
N = 100
x = np.random.random(N)
y = np.random.random(N)
z = np.random.random(N)
ax.scatter(x, y, z)
plt.tight_layout() # <-- Without this, everything is fine
plt.savefig('scatter.png')
In matplotlib 2.2.3 this makes a figure like so:
Similar output is generated by older versions, at least back to 1.5.1. When using the new version 3.0.0, something goes wrong at plt.tight_layout()
and I get the following output:
Accompanying this is the warning
.../matplotlib/tight_layout.py:177: UserWarning: The left and right margins cannot be made large enough to accommodate all axes decorations
One may argue that using tight_layout
with no arguments as here does not (on older matplotlibs) consistently lead to the expected tightened margins anyway, and so one should refrain from using tight_layout
with 3D plots in the first place. However, by manually tweaking the arguments to tight_layout
it is (used to be) a decent way to trim the margins even on 3D plots.
My guess is that this is a bug in matplotlib, but maybe they've made some deliberate change I havn't picked up on. Any pointers about a fix is appreciated.
Thanks to the comment by ImportanceOfBeingErnest, it now works:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import proj3d
fig = plt.figure()
ax = fig.gca(projection='3d')
N = 100
x = np.random.random(N)
y = np.random.random(N)
z = np.random.random(N)
ax.scatter(x, y, z)
# The fix
for spine in ax.spines.values():
spine.set_visible(False)
plt.tight_layout()
plt.savefig('scatter.png')
From the links in the comment, it seems that this will be fixed in matplotlib 3.0.x. For now, the above may be used.