2012-06-21 8 views
51

Ich suche, wie etwas mit weniger Anleitung wie möglich mit Matplotlib zu plotten, aber ich finde keine Hilfe dafür in der Dokumentation.Python/Matplotlib: Plotten eines 3D-Würfels, einer Kugel und eines Vektors?

Ich möchte die folgenden Dinge zeichnen:

  • ein Drahtgitter-Würfel von 2 in 0 mit einer Seitenlänge zentriert
  • ein „Drahtrahmen“ Kugel in 0 mit einem Radius von 1 zentriert
  • ein Punkt an den Koordinaten [0, 0, 0]
  • einen Vektor, der an dieser Stelle beginnt und geht zu [1, 1, 1]

Wie das zu tun?

+3

Überprüfen Sie auch [mayavi2] (http://docs.entdecken.com/mayavi/mayavi/auto/examples.html). Es ist ein bisschen dependency heavy, hat aber einige wirklich tolle high-level Befehle. Ich kann eine detailliertere Antwort basierend auf diesem Paket zusammenstellen, falls gewünscht. . . – meawoppl

Antwort

134

Es ist ein wenig kompliziert, aber man kann durch den folgenden Code alle Objekte zeichnen:

from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
import numpy as np 
from itertools import product, combinations 


fig = plt.figure() 
ax = fig.gca(projection='3d') 
ax.set_aspect("equal") 

# draw cube 
r = [-1, 1] 
for s, e in combinations(np.array(list(product(r, r, r))), 2): 
    if np.sum(np.abs(s-e)) == r[1]-r[0]: 
     ax.plot3D(*zip(s, e), color="b") 

# draw sphere 
u, v = np.mgrid[0:2*np.pi:20j, 0:np.pi:10j] 
x = np.cos(u)*np.sin(v) 
y = np.sin(u)*np.sin(v) 
z = np.cos(v) 
ax.plot_wireframe(x, y, z, color="r") 

# draw a point 
ax.scatter([0], [0], [0], color="g", s=100) 

# draw a vector 
from matplotlib.patches import FancyArrowPatch 
from mpl_toolkits.mplot3d import proj3d 


class Arrow3D(FancyArrowPatch): 

    def __init__(self, xs, ys, zs, *args, **kwargs): 
     FancyArrowPatch.__init__(self, (0, 0), (0, 0), *args, **kwargs) 
     self._verts3d = xs, ys, zs 

    def draw(self, renderer): 
     xs3d, ys3d, zs3d = self._verts3d 
     xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M) 
     self.set_positions((xs[0], ys[0]), (xs[1], ys[1])) 
     FancyArrowPatch.draw(self, renderer) 

a = Arrow3D([0, 1], [0, 1], [0, 1], mutation_scale=20, 
      lw=1, arrowstyle="-|>", color="k") 
ax.add_artist(a) 
plt.show() 

output_figure

5

Für Zeichnung nur auf den Pfeil, gibt es eine einfachere Methode: -

from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
fig = plt.figure() 
ax = fig.gca(projection='3d') 
ax.set_aspect("equal") 

#draw the arrow 
ax.quiver(0,0,0,1,1,1,length=1.0) 

plt.show() 

Köcher kann tatsächlich verwendet werden, um mehrere Vektoren auf einmal zu plotten. Die Verwendung ist wie folgt: - [from http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html?highlight=quiver#mpl_toolkits.mplot3d.Axes3D.quiver]

Köcher (X, Y, Z, U, V, W, ** kwargs)

Argumente:

X, Y, Z : Die x, y und z-Koordinaten der Orte Pfeil

U, V, W: Die x-, y- und z-Komponenten der Pfeilvektoren

Die Argumente könnten Array-artig oder Skalare sein.

Schlüsselwort Argumente:

Länge: [1,0 | float] Die Länge jeder Köcher, default bis 1,0, ist die Einheit, das gleiche mit den Achsen

arrow_length_ratio: [0,3 | Schwimmer] Das Verhältnis der Pfeilspitze in Bezug auf die Köcher, standardmäßig auf 0,3

Dreh: [ ‚Schwanz‘ | 'Mitte' | 'Tip'] Der Teil des Pfeils, der am Gitterpunkt ist; der Pfeil rotiert um diesen Punkt, daher der Name pivot. Standard ist 'tail'

normalisieren: [Falsch | True] Wenn True, sind alle Pfeile gleich lang. Dies ist standardmäßig False, wobei die Pfeile abhängig von den Werten von u, v, w unterschiedliche Längen haben.