web-dev-qa-db-fra.com

traçage de vecteurs 3d à l'aide de matplotlib

J'essaie de tracer des vecteurs en 3D en utilisant matplotlib. J'ai utilisé le code suivant basé sur un exemple précédent de traçage de vecteurs 2D, mais j'ai ajouté des composants pour les vecteurs 3D.

#!/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()

Des idées sur la façon de modifier cela pour créer un tracé vectoriel 3D?

15
jms1980

Vous devez utiliser Axes3D à partir de mplot3d dans mpl_toolkits, puis définir la projection du sous-tracé à 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()

Remarque: Une ancienne version de matplotlib donne souvent des erreurs pour ce code. Essayez d'utiliser au moins la version 1.5

produced_output

18
Tim B

D'après les autres réponses et commentaires, il existe clairement une différence entre les versions de matplotlib. Cependant, je pense que la réponse de Tim B ne répond pas à la question. Les carquois tracés ne représentent pas les vecteurs donnés, car leurs grandeurs ne sont pas correctement représentées. De plus, les pointes de flèches semblent reposer aux points de départ prévus des vecteurs.

Ce qui suit, adapté du code de la réponse précédente, produit le résultat souhaité dans python2.7 avec matplotlib1.5.3. Pour visualiser un vecteur, définissez le point de pivot sur pivot='tail' et la mise à l'échelle du carquois par la grandeur du vecteur a l'effet souhaité. La pointe de flèche du carquois est mise à l'échelle comme un rapport de la longueur du carquois. Ici, je divise le facteur d'échelle par la magnitude du vecteur pour rendre toutes les pointes de flèche de la même taille avec arrow_length_ratio=0.3/vlength.

Mauvais points - Mon code n'est pas très compact. J'ai dû fournir X, Y, Z, U, V, W sous une forme décompressée afin d'utiliser différents kwargs pour chaque appel à ax.quiver. Si quelqu'un peut suggérer une modification qui contient des kwargs, je serais extrêmement reconnaissant.

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()

Sortie: Tracé des vecteurs sous forme de carquois avec matplotlib-1.5.3.

3
Dave