绘制三维向量。

27

我正在尝试使用matplotlib绘制三维向量。我使用了以下代码,基于以前绘制二维向量的示例,但添加了三维向量的组件。

#!/usr/bin/python

import numpy as np
import matplotlib.pyplot as plt

soa =np.array( [ [0,0,1,1,-2,0], [0,0,2,1,1,0],[0,0,3,2,1,0],[0,0,4,0.5,0.7,0]]) 

X,Y,Z,U,V,W = zip(*soa)
plt.figure()
ax = plt.gca()
ax.quiver(X,Y,Z,U,V,W,angles='xyz',scale_units='xyz',scale=1,color='b')
ax.set_xlim([-1,10])
ax.set_ylim([-1,10])
ax.set_zlim([10,1])
plt.draw()
plt.show()

有什么想法可以调整这个代码以制作一个3D向量图吗?
2个回答

33

您需要在mpl_toolkits中使用mplot3d中的Axes3D,然后将子图投影设置为3D:

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

soa = np.array([[0, 0, 1, 1, -2, 0], [0, 0, 2, 1, 1, 0],
                [0, 0, 3, 2, 1, 0], [0, 0, 4, 0.5, 0.7, 0]])

X, Y, Z, U, V, W = zip(*soa)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.quiver(X, Y, Z, U, V, W)
ax.set_xlim([-1, 0.5])
ax.set_ylim([-1, 1.5])
ax.set_zlim([-1, 8])
plt.show()

注意:旧版的matplotlib经常会在这段代码中出错。请尝试使用至少1.5版本。

produced_output


4
我尝试按照你的建议进行操作,但是出现了一个错误:AttributeError: 'Quiver'对象没有属性'do_3d_projection',我该如何解决? - jms1980
matplotlib 1.3.1。如何获得版本1.4.2?我通过sudo yum安装获取了我的版本。 - jms1980
如果您正在使用 Fedora(基于您使用 yum 的事实做出的假设),那么 1.3.1 似乎是常规仓库中可用的最新版本。您可以从源代码构建 matplotlib,有相关的说明在这里。这将让您使用最新版本。 - Tim B
2
你还可以执行pip install matplotlib --upgrade来升级。 - farenorth
1
除了Tim B的答案之外,您使用的matplolib版本也非常重要。matplotlib 1.3.1似乎存在问题,这些问题在1.4.2和尤其是现在的1.5.1中得到了解决。 - stochastic
显示剩余2条评论

5
从其他答案和评论中可以看出,matplotlib的版本存在明显差异。然而,我认为Tim B的答案并没有回答这个问题。绘制的箭头不代表给定的向量,因为它们的大小没有得到正确的表示。此外,箭头似乎坐落在向量的起始点。
下面的代码是基于之前答案中的代码,它在python2.7和matplotlib1.5.3中产生了期望的结果。为了可视化一个向量,将枢轴点设置为“tail”,并通过向量的大小来缩放quiver可以达到预期的效果。quiver箭头的大小与quiver长度的比例有关。在这里,我将缩放因子除以向量的大小,以使所有箭头的大小相同,使用arrow_length_ratio=0.3/vlength。
缺点 - 我的代码不太紧凑。我必须以未打包的形式提供X、Y、Z、U、V、W,以便对每次调用ax.quiver使用不同的kwargs。如果有人能建议一种编辑方法,将kwargs打包,我将非常感激。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

vectors=np.array( [ [0,0,1,1,-2,0], [0,0,2,1,1,0],[0,0,3,2,1,0],[0,0,4,0.5,0.7,0]]) 
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for vector in vectors:
    v = np.array([vector[3],vector[4],vector[5]])
    vlength=np.linalg.norm(v)
    ax.quiver(vector[0],vector[1],vector[2],vector[3],vector[4],vector[5],
            pivot='tail',length=vlength,arrow_length_ratio=0.3/vlength)
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([0,4])
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.show()

输出: 使用matplotlib-1.5.3绘制向量箭头图。


1
在matplotlib 2.0.0中,箭头长度已经正确缩放以实现此功能,因此ax.quiver(vector[0], vector[1], vector[2], vector[3], vector[4], vector[5], pivot='tail', length=vlength, arrow_length_ratio=0.3/vlength)应更改为ax.quiver(vector[0], vector[1], vector[2], vector[3], vector[4], vector[5], pivot='tail', arrow_length_ratio=0.3/vlength)或者使用zipped数组(请参见Tim B的答案)返回至ax.quiver(X, Y, Z, U, V, W, pivot='tail'),如果您不需要缩放的箭头。 - Dave

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