设置3D p的纵横比

2024-09-26 18:14:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图从500米乘40米的海底声纳数据中绘制出海底的三维图像。我将matplotlib/mplot3d与Axes3D一起使用,希望能够更改轴的纵横比,以便缩放x&y轴。使用生成的数据而不是实际数据的示例脚本是:

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

# Create figure.
fig = plt.figure()
ax = fig.gca(projection = '3d')

# Generate example data.
R, Y = np.meshgrid(np.arange(0, 500, 0.5), np.arange(0, 40, 0.5))
z = 0.1 * np.abs(np.sin(R/40) * np.sin(Y/6))

# Plot the data.
surf = ax.plot_surface(R, Y, z, cmap=cm.jet, linewidth=0)
fig.colorbar(surf)

# Set viewpoint.
ax.azim = -160
ax.elev = 30

# Label axes.
ax.set_xlabel('Along track (m)')
ax.set_ylabel('Range (m)')
ax.set_zlabel('Height (m)')

# Save image.
fig.savefig('data.png')

以及此脚本的输出图像:

matplotlib output image

现在我想改变它,使沿轨道(x)轴的1米与沿范围(y)轴的1米相同(或者根据所涉及的相对大小,可能有不同的比率)。我还想设置z轴的比率,同样由于数据中的相对大小,不一定要设置为1:1,但是轴比当前绘图要小。

我试着按照this message from the mailing list中的示例脚本来构建和使用this branch of matplotlib,但在脚本中添加ax.pbaspect = [1.0, 1.0, 0.25]行(卸载了matplotlib的“标准”版本以确保使用了自定义版本)并没有对生成的图像产生任何影响。

编辑:因此所需的输出类似于以下(用Inkscape粗略编辑)图像。在本例中,我没有在x/y轴上设置1:1的比率,因为它看起来非常薄,但是我已经展开它,所以它不像原始输出那样是正方形的。

Desired output


Tags: 数据from图像import脚本示例datamatplotlib
3条回答

我解决了浪费空间的问题:

try: 
    self.localPbAspect=self.pbaspect
    zoom_out = (self.localPbAspect[0]+self.localPbAspect[1]+self.localPbAspect[2]) 
except AttributeError: 
    self.localPbAspect=[1,1,1]
    zoom_out = 0 
xmin, xmax = self.get_xlim3d() /  self.localPbAspect[0]
ymin, ymax = self.get_ylim3d() /  self.localPbAspect[1]
zmin, zmax = self.get_zlim3d() /  self.localPbAspect[2]

# transform to uniform world coordinates 0-1.0,0-1.0,0-1.0
worldM = proj3d.world_transformation(xmin, xmax,
                                         ymin, ymax,
                                         zmin, zmax)

# look into the middle of the new coordinates
R = np.array([0.5*self.localPbAspect[0], 0.5*self.localPbAspect[1], 0.5*self.localPbAspect[2]])
xp = R[0] + np.cos(razim) * np.cos(relev) * (self.dist+zoom_out)
yp = R[1] + np.sin(razim) * np.cos(relev) * (self.dist+zoom_out)
zp = R[2] + np.sin(relev) * (self.dist+zoom_out)
E = np.array((xp, yp, zp))

this question的回答对我来说非常有效。不需要设置任何比率,它会自动执行所有操作。

在savefig之前添加以下代码:

ax.auto_scale_xyz([0, 500], [0, 500], [0, 0.15])

enter image description here

如果不需要方轴:

编辑网站包中的get_proj函数\mpl_toolkits\mplot3d\axes3d.py:

xmin, xmax = np.divide(self.get_xlim3d(), self.pbaspect[0])
ymin, ymax = np.divide(self.get_ylim3d(), self.pbaspect[1])
zmin, zmax = np.divide(self.get_zlim3d(), self.pbaspect[2])

然后添加一行设置pbaspect:

ax = fig.gca(projection = '3d')
ax.pbaspect = [2.0, 0.6, 0.25]

enter image description here

相关问题 更多 >

    热门问题