【问题标题】:How to keep hemisphere the correct shape in matplotlib 3D plot as I rotate the view?当我旋转视图时,如何在 matplotlib 3D 图中保持半球的正确形状?
【发布时间】:2019-09-12 07:02:52
【问题描述】:

我希望能够在 3D matplotlib 图中旋转半球的视图并正确显示形状,

第一个示例中使用的set matplotlib 3d plot aspect ratio? 的答案无济于事,因为它们解决了绘图窗口的纵横比问题。

问题:在第二个例子中,我展示了如果我让比例尺等长 (-1, 1), (-1, 1), (-0.5, 1.5) 我可以保留旋转视图时的形状,但这是在视图旋转下保留形状的唯一方法吗?

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

points   = np.random.random((3, 1000)) - 0.5
points  /= np.sqrt((points**2).sum(axis=0))
x, y, z  = points[:, points[2] > 0.]  # upper hemisphere

fig = plt.figure(figsize=plt.figaspect(0.5)) # https://stackoverflow.com/a/12371373/3904031

ax1 = fig.add_subplot(2, 1, 1, projection='3d')
ax1.plot(x, y, z, '.k')
ax1.view_init(0, 90)
ax1.set_title('view_init(0, 90)', fontsize=16)

ax2 = fig.add_subplot(2, 1, 2, projection='3d')
ax2.plot(x, y, z, '.k')
ax2.view_init(90, 0)
ax2.set_title('view_init(90, 0)', fontsize=16)

plt.show()

fig = plt.figure()

ax1 = fig.add_subplot(1, 2, 1, projection='3d')
ax1.plot(x, y, z, '.k')
ax1.view_init(0, 90)
ax1.set_title('view_init(0, 90)', fontsize=16)
ax1.set_xlim(-1.0, 1.0)
ax1.set_ylim(-1.0, 1.0)
ax1.set_zlim(-0.5, 1.5)

ax2 = fig.add_subplot(1, 2, 2, projection='3d')
ax2.plot(x, y, z, '.k')
ax2.view_init(90, 0)
ax2.set_title('view_init(90, 0)', fontsize=16)
ax2.set_xlim(-1.0, 1.0)
ax2.set_ylim(-1.0, 1.0)
ax2.set_zlim(-0.5, 1.5)

plt.show()

【问题讨论】:

  • 是的,您需要使用相等的纵横比。这对于 3D 绘图来说并不容易,但 stackoverflow.com/questions/13685386/… 会展示一些方法来做到这一点
  • @ImportanceOfBeingErnest 好的,感谢您的快速回复。所以对于第二个例子,我使用了 set_xlim(-1.0, 1.0); set_ylim(-1.0, 1.0); set_zlim(-0.5, 1.5) 类似于this answer,但我可以使用不可见的边界点,如this answer 所示。所以无论哪种方式,这可能都是重复的,可以这样关闭吗?还是有可能即将使用.axis('all_three_equal') 方法?
  • 没有可用的.axis('all_three_equal') 方法。
  • @ImportanceOfBeingErnest 因此是关于其紧迫性的问题。换句话说,如果有机会在不久的将来出现,那么它将作为这个问题的答案。但是,如果添加类似内容的可能性很小,那么最好将其作为副本关闭。
  • 即使迫在眉睫,这样的答案难道不会存在于副本中吗?

标签: python python-3.x matplotlib


【解决方案1】:

最后,根据this answer

简单修复!

我已经设法在 3.3.1 版本中实现了这个功能。

看起来这个问题在PR#17172 中可能已经解决了;您可以使用ax.set_box_aspect([1,1,1]) 函数来确保方面正确(请参阅set_aspect 函数的注释)。

您首先通过添加边界点(数据之外的不可见点)来定义相同尺寸的立方体,或者像我在这里所做的那样使用 set_xlim、set_ylim、set_zlim,从而使所有三个轴的限制都相同。

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

points   = np.random.random((3, 1000)) - 0.5
points  /= np.sqrt((points**2).sum(axis=0))
x, y, z  = points[:, points[2] > 0.]  # upper hemisphere

fig = plt.figure(figsize=plt.figaspect(0.5)) # https://stackoverflow.com/a/12371373/3904031

ax1 = fig.add_subplot(1, 2, 1, projection='3d')
ax1.plot(x, y, z, '.k')
ax1.view_init(0, 90)
ax1.set_title('view_init(0, 90)', fontsize=16)

ax2 = fig.add_subplot(1, 2, 2, projection='3d')
ax2.plot(x, y, z, '.k')
ax2.view_init(90, 0)
ax2.set_title('view_init(90, 0)', fontsize=16)

for ax in (ax1, ax2):
    ax.set_xlim(-1, 1)
    ax.set_ylim(-1, 1)
    ax.set_zlim(-0.5, 1.5)
    ax.set_box_aspect([1,1,1])
plt.show()

【讨论】:

    猜你喜欢
    • 2012-12-18
    • 1970-01-01
    • 2021-08-13
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 2015-07-23
    相关资源
    最近更新 更多