Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

plotting 3d vectors using Python matplotlib

Tags:

I am trying to plot vectors in 3d using matplotlib. I used the following code based on a previous example of plotting 2d vectors but added components for 3d vectors.

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

Any ideas on how to tweak this to make a 3d vector plot?

like image 595
jms1980 Avatar asked Nov 19 '14 17:11

jms1980


People also ask

Can matplotlib plot 3D images?

Among these, Matplotlib is the most popular choice for data visualization. While initially developed for plotting 2-D charts like histograms, bar charts, scatter plots, line plots, etc., Matplotlib has extended its capabilities to offer 3D plotting modules as well.

How do you plot a 3D plot in Python?

Plotting 3-D Lines and Points Graph with lines and point are the simplest 3 dimensional graph. ax. plot3d and ax. scatter are the function to plot line and point graph respectively.


2 Answers

You need to use Axes3D from mplot3d in mpl_toolkits, then set the subplot projection to 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()

Note: Older version of matplotlib often give errors for this code. Try to use at least version 1.5

produced_output

like image 165
Tim B Avatar answered Oct 06 '22 02:10

Tim B


From other answers and comments, there is clearly a difference between matplotlib versions. However, I believe Tim B's answer does not answer the question. The quivers plotted do not represent the given vectors, since their magnitudes are not properly represented. Also, the arrowheads appear to sit at the intended start points of the vectors.

The following, adapted from the code in the previous answer, produces the desired result in python2.7 with matplotlib1.5.3. To visualise a vector, setting the pivot point to pivot='tail' and scaling the quiver by the magnitude of the vector has the desired effect. The quiver arrowhead is scaled as a ratio of the quiver length. Here I divide the scaling factor by the magnitude of the vector to make all arrowheads the same size with arrow_length_ratio=0.3/vlength.

Bad points - My code isn't very compact. I've had to provide X,Y,Z,U,V,W in an unpacked form in order to use different kwargs for each call to ax.quiver. If anyone can suggest an edit that packs kwargs I'd be extremely grateful.

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

Output: Plot of vectors as quivers with matplotlib-1.5.3.

like image 44
Dave Avatar answered Oct 06 '22 01:10

Dave