Zeichnen eines 3D-Würfels, einer Kugel und eines Vektors in Matplotlib

79

Ich suche, wie ich mit Matplotlib etwas mit weniger Anweisungen als möglich zeichnen kann, aber ich finde keine Hilfe dafür in der Dokumentation.

Ich möchte folgende Dinge zeichnen:

  • ein in 0 zentrierter Drahtgitterwürfel mit einer Seitenlänge von 2
  • eine "Drahtgitter" -Kugel, die in 0 mit einem Radius von 1 zentriert ist
  • ein Punkt an den Koordinaten [0, 0, 0]
  • ein Vektor, der an diesem Punkt beginnt und zu [1, 1, 1] geht

Wie geht das?

Vincent
quelle
3
Schauen Sie sich auch mayavi2 an . Es ist ein bisschen abhängig, hat aber einige wirklich großartige Befehle auf hoher Ebene. Auf Wunsch kann ich anhand dieses Pakets eine detailliertere Antwort zusammenstellen. . .
Meawoppl

Antworten:

179

Es ist etwas kompliziert, aber Sie können alle Objekte mit dem folgenden Code 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

HYRY
quelle
11

Um nur den Pfeil zu zeichnen, 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 zeichnen. Die Verwendung ist wie folgt: - [von 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 Pfeilpositionen

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

Die Argumente können Array-ähnlich oder skalar sein.

Schlüsselwortargumente:

Länge: [1.0 | float] Die Länge jedes Köchers, standardmäßig 1,0, die Einheit ist mit den Achsen gleich

pfeillänge_verhältnis: [0.3 | float] Das Verhältnis der Pfeilspitze zum Köcher ist standardmäßig 0,3

Drehpunkt: ['Schwanz' | 'Mitte' | 'tip'] Der Teil des Pfeils, der sich am Gitterpunkt befindet; Der Pfeil dreht sich um diesen Punkt, daher der Name Pivot. Die Standardeinstellung ist "Schwanz".

normalisieren: [False | True] Wenn True, sind alle Pfeile gleich lang. Der Standardwert ist False, wobei die Pfeile abhängig von den Werten von u, v, w unterschiedlich lang sind.

Aritra
quelle
0

Meine Antwort ist eine Zusammenführung der beiden oben genannten Punkte mit einer Erweiterung auf die Zeichensphäre mit benutzerdefinierter Deckkraft und einigen Anmerkungen. Es findet Anwendung in der B-Vektor-Visualisierung auf einer Kugel für das Magnetresonanzbild (MRT). Ich hoffe, Sie finden es nützlich:

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

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

# draw sphere
u, v = np.mgrid[0:2*np.pi:50j, 0:np.pi:50j]
x = np.cos(u)*np.sin(v)
y = np.sin(u)*np.sin(v)
z = np.cos(v)
# alpha controls opacity
ax.plot_surface(x, y, z, color="g", alpha=0.3)


# a random array of 3D coordinates in [-1,1]
bvecs= np.random.randn(20,3)

# tails of the arrows
tails= np.zeros(len(bvecs))

# heads of the arrows with adjusted arrow head length
ax.quiver(tails,tails,tails,bvecs[:,0], bvecs[:,1], bvecs[:,2],
          length=1.0, normalize=True, color='r', arrow_length_ratio=0.15)

ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.set_zlabel('Z-axis')

ax.set_title('b-vectors on unit sphere')

plt.show()
tash
quelle
Bitte erläutern Sie, [0:2*np.pi:50j, 0:np.pi:50j]wie dieses Slice funktioniert. Was ist der Radius und der Mittelpunkt der Kugel in analytischer Hinsicht?
Ragnar