2014-11-19 9 views
12

Próbuję wykreślić wektory w 3d przy użyciu matplotlib. Użyłem następującego kodu na podstawie poprzedniego przykładu wykreślania wektorów 2d, ale dodałem komponenty do wektorów 3d.wykreślając wektory 3D za pomocą matplot lib

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

Jakieś pomysły na ulepszenie tego, aby stworzyć trójwymiarowy wektor fabuły?

Odpowiedz

11

Trzeba użyć Axes3D z mplot3d w mpl_toolkits, a następnie ustawić projekcję poletko do 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() 

UWAGA: starsza wersja matplotlib często dają błędów dla tego kodu. Spróbuj użyć w wersji co najmniej 1.5

produced_output

+4

Próbowałem robić to, co sugeruje, ale pojawia się błąd: AttributeError: obiekt „kołczan” nie ma atrybutu „do_3d_projection jak mogę rozwiązać ten problem? – jms1980

+0

@ jms1980 To dziwne, próbowałem go w python 2 i python 3 i działa dobrze dla mnie. Jaki błąd dostałeś? –

+0

@ jms1980 Jaką wersję macierzy matplotlib masz? Używam najnowszej stabilnej wersji 1.4.2. –

2

Z innych odpowiedzi i komentarze, istnieje wyraźna różnica między wersjami matplotlib. Uważam jednak, że odpowiedź Tima B nie odpowiada na pytanie. Zadrapane linie nie reprezentują danych wektorów, ponieważ ich wielkości nie są odpowiednio reprezentowane. Ponadto groty wydają się znajdować w zamierzonych punktach początkowych wektorów.

Następujące, dostosowane z kodu w poprzedniej odpowiedzi, daje pożądany wynik w python2.7 z matplotlib1.5.3. Aby wizualizować wektor, ustawienie punktu obrotu na pivot='tail' i skalowanie kołczanu o wielkość wektora ma pożądany efekt. Grot strzały kołczanu jest skalowany jako stosunek długości kołczanu. Tutaj dzielę współczynnik skalowania przez wielkość wektora, aby wszystkie groty były tego samego rozmiaru z arrow_length_ratio=0.3/vlength.

Złe punkty - Mój kod nie jest zbyt kompaktowy. Musiałem dostarczyć X, Y, Z, U, V, W w rozpakowanej formie, aby użyć różnych kwargów dla każdego wywołania ax.quiver. Jeśli ktokolwiek może zaproponować edycję, która pakuje kwargs, byłbym niezmiernie wdzięczny.

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

wyjściowa: Plot of vectors as quivers with matplotlib-1.5.3.

+0

W matplotlib2.0.0 długości drgań są odpowiednio skalowane dla tej funkcji, więc 'ax.quiver (wektor [0], wektor [1], wektor [2], wektor [3], wektor [4], wektor [5] , pivot = "ogon", długość = długość, strzałka długość_statio = 0,3/długość) "należy zmienić na" ax.quiver (wektor [0], wektor [1], wektor [2], wektor [3], wektor [ 4], wektor [5], pivot = "ogon", strzałka długość_statio = 0,3/długość) 'lub z powrotem do' ax.quiver (X, Y, Z, U, V, W, pivot = 'ogon') ' ze spakowaną tablicą (patrz odpowiedź Tima B), jeśli nie potrzebujesz skalowanych grotów strzał. – Dave

Powiązane problemy