在尝试在matplotlib中操作图形时,我遇到了一些有趣的事情。使用绘图功能时,可以通过别名来修改x和y坐标,但是z不能。这容易解释吗?
我提供了一个小示例,请注意,我试图获得沿圆柱体螺旋移动的点。

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

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")

radius = 8

# Cylinder
x = np.linspace(-radius, radius, 100)
z = np.linspace(0, 2, 100)
X, Z = np.meshgrid(x, z)

Y = np.sqrt(radius**2 - X**2)

ax.plot_surface(X, Y, Z, alpha=0.3, linewidth=0)
ax.plot_surface(X, (-Y), Z,alpha=0.3, linewidth=0)

X = np.array(np.zeros(1))
Y = np.array(np.zeros(1))
Z = np.array(np.zeros(1))

X[0]= radius*np.cos(np.deg2rad(0))
Y[0]= radius*np.sin(np.deg2rad(0))
Z[0]= 0.

ax.plot(X,Y,Z, 'or',markersize=3)

for i in range(0,360,5):

    X[0]= radius*np.cos(np.deg2rad(i))
    Y[0]= radius*np.sin(np.deg2rad(i))
    Z[0]= i/140.

    plt.draw()
    plt.pause(0.01)


作为参考,此练习的最终目标是能够基于传感器输入的三维实时定位点。

感谢所有对为什么会发生这种情况以及可能的解决方案有深刻见解的人!

最佳答案

这确实很有趣。Line3D是从Line2D派生的,因此get_xdataset_xdata之类的功能在z方向上也不可用。查看源代码(art3d.py),似乎完全忽略了z值:

def draw(self, renderer):
    xs3d, ys3d, zs3d = self._verts3d
    xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
    self.set_data(xs, ys)
    lines.Line2D.draw(self, renderer)


但是也许我不正确地理解Line3D的工作原理...

但是,可以使用一个函数来操纵z值(set_3d_properties),但是由于该函数调用get_xdataget_ydata本身,因此使它起作用的唯一方法是:

p = ax.plot(X,Y,Z, 'or', markersize=3)[0]

for i in range(0,360,5):
    p.set_xdata(radius*np.cos(np.deg2rad(i)))
    p.set_ydata(radius*np.sin(np.deg2rad(i)))
    p.set_3d_properties(zs=i/140.)

关于python - 3D Matplotlib中的动态点操纵,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37529469/

10-11 20:44