【问题标题】:How do I crop an Axes3D plot with square aspect ratio?如何裁剪具有正方形纵横比的 Axes3D 图?
【发布时间】:2019-07-14 22:43:27
【问题描述】:

这是一个简单的例子:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
f = fig.add_subplot(2, 1, 1, projection='3d')
t = fig.add_subplot(2, 1, 2, projection='3d')

# axes
for d in {f, t}:
    d.plot([-1, 1], [0, 0], [0, 0], color='k', alpha=0.8, lw=2)
    d.plot([0, 0], [-1, 1], [0, 0], color='k', alpha=0.8, lw=2)
    d.plot([0, 0], [0, 0], [-1, 1], color='k', alpha=0.8, lw=2)

f.dist = t.dist = 5.2   # 10 is default

plt.tight_layout()
f.set_aspect('equal')
t.set_aspect('equal')

r = 6
f.set_xlim3d([-r, r])
f.set_ylim3d([-r, r])
f.set_zlim3d([-r, r])

t.set_xlim3d([-r, r])
t.set_ylim3d([-r, r])
t.set_zlim3d([-r, r])

f.set_axis_off()
t.set_axis_off()

plt.draw()
plt.show()

这是我得到的:

这就是我想要的:

换句话说,我希望地块本身具有正方形的纵横比,而不是像这样展开:

感谢https://stackoverflow.com/a/31364297/125507

但我希望查看这些图的窗口是矩形的,顶部和底部被裁剪掉(因为顶部和底部只有空白,并且我正在生成多个动画 GIF,所以我不能轻易发布- 加工成我想要的形状)。

基本上我正在制作这个动画,我想要同样的东西,但没有所有的空白:

【问题讨论】:

标签: python matplotlib aspect-ratio mplot3d


【解决方案1】:

为了跟进我的 cmets 并通过设置较小的 r 并使用 subplots_adjust 删除子图边距来显示示例:

 
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
f = fig.add_subplot(2, 1, 1, projection='3d')
t = fig.add_subplot(2, 1, 2, projection='3d')

# axes
for d in {f, t}:
    d.plot([-1, 1], [0, 0], [0, 0], color='k', alpha=0.8, lw=2)
    d.plot([0, 0], [-1, 1], [0, 0], color='k', alpha=0.8, lw=2)
    d.plot([0, 0], [0, 0], [-1, 1], color='k', alpha=0.8, lw=2)

f.dist = t.dist = 5.2   # 10 is default

plt.tight_layout()
f.set_aspect('equal')
t.set_aspect('equal')

r = 1
f.set_xlim3d([-r, r])
f.set_ylim3d([-r, r])
f.set_zlim3d([-r, r])

t.set_xlim3d([-r, r])
t.set_ylim3d([-r, r])
t.set_zlim3d([-r, r])

f.set_axis_off()
t.set_axis_off()

fig.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
            hspace = 0, wspace = 0)

plt.draw()
plt.show()

这将给出更紧凑的子图,SubplotParams 的默认值如下:

左:0.125

右:0.9

底部:0.1

顶部:0.9

空间:0.2

hspace : 0.2

不知道这是不是 OP 正在寻找的...

【讨论】:

  • 每个图仍然是正方形,但是,我想让它们成为矩形,同时仍然具有相等的轴
【解决方案2】:

由于您想要矩形绘图,因此不能使用set_aspect('equal'),而是必须调整绘图的限制以解决纵横比的差异。

在下面的尝试中,我使用轴的bbox 来获取轴的heightwidth,并使用纵横比重新缩放XY 轴。 (我假设两个图具有相同的尺寸,但你也可以有不同尺寸的图,您只需为每个图单独调整轴限制)。

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
f = fig.add_subplot(2, 1, 1, projection='3d')
t = fig.add_subplot(2, 1, 2, projection='3d')

# axes
for d in {f, t}:
    d.plot([-1, 1], [0, 0], [0, 0], color='k', alpha=0.8, lw=2)
    d.plot([0, 0], [-1, 1], [0, 0], color='k', alpha=0.8, lw=2)
    d.plot([0, 0], [0, 0], [-1, 1], color='k', alpha=0.8, lw=2)

f.dist = t.dist = 5.2   # 10 is default

plt.tight_layout()
# Cannot use 'equal' aspect for a rectangular plot
# f.set_aspect('equal')
# t.set_aspect('equal')

# get the dimensions of the axes from its bbox
f_bbox = f.get_position()
f_height = f_bbox.height
f_width = f_bbox.width


r = 6
f.set_xlim3d([-1 * f_width/f_height * r, f_width/f_height * r])
f.set_ylim3d([-1 * f_width/f_height * r, f_width/f_height * r])
f.set_zlim3d([-r, r])

t.set_xlim3d([-1 * f_width/f_height * r, f_width/f_height * r])
t.set_ylim3d([-1 * f_width/f_height * r, f_width/f_height * r])
t.set_zlim3d([-r, r])

f.set_axis_off()
t.set_axis_off()

plt.draw()
plt.show()

注意:在这张图片中,我添加了背景颜色以突出显示地块的矩形形状

【讨论】:

  • 它们在旋转时不会保持纵横比。视口需要裁剪成一个矩形,而不是缩小成一个
猜你喜欢
  • 1970-01-01
  • 2014-02-16
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多