Matplotlib 3:紧凑布局的3D散点图

5

我有一些代码,使用matplotlib的scattertight_layout来生成3D散点图,请看下面简化的代码:

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')

在matplotlib 2.2.3中,这将生成如下图所示的图形:enter image description here
旧版中也会生成类似的输出,至少可以追溯到1.5.1。但使用新版本3.0.0时,在plt.tight_layout()上出了点问题,输出如下:enter image description here
对应的警告是:

.../matplotlib/tight_layout.py:177: UserWarning: The left and right margins cannot be made large enough to accommodate all axes decorations

有人可能会认为在老版本中使用没有参数的tight_layout并不总能使边距变窄,因此应该在首次使用3D绘图时避免使用tight_layout。但是,通过手动调整tight_layout的参数,它(已经)是一种修剪3D图边缘的不错方法。
我猜这可能是matplotlib的一个bug,但也许他们进行了一些有意的更改我还没有理解。如果您有任何有关修复的指示,将不胜感激。

可能无法正常工作,但一个可能的解决方法是显式地设置图形的大小,而不是使用tight_layout,例如,plt.figure(figsize=(20,10))。 - Dr.PP
设置 figsize 不等同于 tight_layout。此外,我已经在我的实际代码中设置了 figsize,因为我关心最终图像的精确像素大小。 - jmd_dk
1
这是问题所在:https://github.com/matplotlib/matplotlib/issues/12239,而这是修复方案:https://github.com/matplotlib/matplotlib/pull/12241。我想你可以手动应用它,即在调用“tight_layout”之前使脊柱不可见。 - ImportanceOfBeingErnest
2个回答

3

感谢 ImportanceOfBeingErnest 的评论,现在它已经可用:

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')

从评论中的链接来看,这个问题似乎会在 matplotlib 3.0.x 中得到修复。目前,可以使用上述方法。

1
我遇到了一个类似的问题,但在我的情况下,在3.0.1中仍然无法解决,而您的修复程序不再需要。结果发现matplotlib似乎还有另一个错误(现已报告):如果在调用之前添加文本到3D轴,则会破坏tight_layout()。将其作为已知的工作示例对于找出问题至关重要,所以谢谢! - Energya

-2
plt.tight_layout()
plt.show()

就在你的主体绘图代码下面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接