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?
python
matplotlib
3d
geometry
Vincent
quelle
quelle
Antworten:
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()
quelle
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.
quelle
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()
quelle
[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?