[Achtung] Dieser Artikel wurde im Dezember 2016 veröffentlicht. Der folgende Code ist für Julia 0.6.
Julia Adventskalender 2016 Dies ist der Artikel am 6. Tag.
Versuchen wir, eine Bibliothek namens MayaVi von Julia zu verwenden, die kürzlich mit einem Conda-Paket versehen wurde.
MayaVi ist ein Paket für 3D-Diagramme. Der Umriss ist wie folgt.
Eine Bibliothek mit einem ähnlichen Charakter ist ParaView (http://www.paraview.org). Dies zielt auf eine parallele Dezentralisierung ab und ist wahrscheinlich berühmter als MayaVi. Ich habe zuerst mit MayaVi angefangen und hatte große Probleme bei der Installation von ParaView. Die Benutzerfreundlichkeit ist ähnlich und MayaVi wird für persönliche Projekte empfohlen.
Der Umgang mit Conda-Paketen in Julia wurde im gestrigen Artikel erklärt. (Conda-Paket von Julia hinzufügen)
Verwenden Sie Conda.add ()
, um das Mayavi-Paket zur von Julia installierten Miniconda-Umgebung hinzuzufügen.
julia> using Conda
julia> Conda.add("mayavi")
Using Anaconda Cloud api site https://api.anaconda.org
Fetching package metadata .......
Solving package specifications: ..........
# All requested packages already installed.
# packages in environment at /Users/hs/.pyenv/versions/anaconda-2.4.0/envs/conda_jl:
...Folgendes wird weggelassen.
Wenn Sie Mayavi zu Ihrer eigenen Anaconda-Umgebung hinzufügen möchten, können Sie den Befehl conda über die Shell (Befehlszeile, Terminal) eingeben.
$ conda install mayavi -n conda_jl
Using Anaconda Cloud api site https://api.anaconda.org
Fetching package metadata .............
Solving package specifications: ..........
Package plan for installation in environment /Users/hs/.pyenv/versions/anaconda-2.4.0/envs/conda_jl:
...Folgendes wird weggelassen.
MayaVi functions gallery
Versuchen Sie zunächst das Beispiel in MayaVi-Funktionsgalerie.
julia> using PyCall
julia> @pyimport mayavi.mlab as mlab
julia> mlab.test_plot3d()
PyObject <mayavi.modules.glyph.Glyph object at 0x337fc95f0>
julia> mlab.show()
Quelldatei oben: plot3d () https://gist.github.com/d4578e1f4d22bbfa0f418f0caff239c7
Ausführungsergebnis (Screenshot)
mayavi.mlab
ist ein Tool zum einfachen Plotten von Pythons numpy.array
. Wenn Sie matplotlib
kennen, können Sie erraten, dass es matplotlib.pyplot
entspricht?
Wenn Sie mlab.show ()
starten, wird das eigentliche Zeichnen durchgeführt. Am oberen Rand des 3D-Diagramms befindet sich eine Menüleiste mit mehreren Symbolen, mit der Sie die Figur drehen und skalieren können. Die Funktion hier heißt "Merkmale" (keine gute Übersetzung gefunden).
Jetzt wurden auch die anderen acht Beispiele in der Mayavi-Funktionsgalerie erfolgreich angezeigt. Fügen Sie die Quelldatei in den Kern ein. --Punkte (Kugel) Punkte3d (): https://gist.github.com/a3b0b95b58a42b7b010aea779536e6f3 --Image imshow (): https://gist.github.com/326f9b72a56f6187f0d62b7e9e3ca4ed
Ausführungsergebnis von test_mesh () (Screenshot)
surface_from_irregular_data
Im Folgenden finden Sie vier Beispielprogramme, die Tipps und verwandte Tipps zum Portieren von Mayavi-Programmen in Python nach Julia enthalten. Es ist ein Programm namens "surface_from_irregular_data.py".
function f(x, y)
exp(-(x .^ 2 + y .^ 2))
end
srand(12345)
xs = 4.0 * (rand(500) - 0.5)
ys = 4.0 * (rand(500) - 0.5)
zs = f(xs, ys)
using PyCall
@pyimport mayavi.mlab as mlab
mlab.figure(1, fgcolor=(0, 0, 0), bgcolor=(1, 1, 1))
# Visualize the points
pts = mlab.points3d(xs, ys, zs, zs, scale_mode="none", scale_factor=0.2)
# Create and visualize the mesh
mesh = mlab.pipeline[:delaunay2d](pts)
surf = mlab.pipeline[:surface](mesh)
mlab.view(47, 57, 8.2, (0.1, 0.15, 0.14))
mlab.show()
Ausführungsergebnis (Screenshot)
Erweitern Sie einen unregelmäßigen zweidimensionalen Punkt "(x, y)" mit der Funktion "z = f (x, y)" zu einem dreidimensionalen Punkt "(x, y, z)". Zeichnen Sie sie als Punkte (Kugeln) (points3d). Es interpoliert auch 3D-Punkte (delaunay2d) und zeichnet seine Oberfläche (Brandung). Das Hinzufügen einer Verarbeitung zu den Daten wird als Pipeline bezeichnet.
Die Julia-Quelle ist fast dieselbe wie die Python-Quelle. Ich habe auf folgende Punkte geachtet.
--Pythons mlab.pipeline.delaunay2d
usw. kann nicht so aufgerufen werden, wie es ist, aber es heißt mlab.pipeline [: delaunay2d]
.
function
wurde die Leistung jedes Elements auf korrigiert. ^
.triangular_mesh
Versuchen Sie als nächstes, das Programm in test_triangular_mesh
nach Julia zu portieren.
# An example of a cone, ie a non-regular mesh defined by its triangles.
n = 8
t = linspace(-pi, pi, n)
xy = exp(im * t)
x = real(xy)
y = imag(xy)
z = zeros(n)
triangles = [ (0, i, i + 1) for i in 1:n-1 ]
unshift!(x,0.0)
unshift!(y,0.0)
unshift!(z,1.0)
t=collect(t)
unshift!(t,0.0)
using PyCall
@pyimport mayavi.mlab as mlab
mlab.triangular_mesh(x, y, z, triangles, scalars=PyObject(t))
mlab.show()
Ausführungsergebnis (Screenshot) * Die Figur wird reduziert / gedreht:
mlab.triangular_mesh
ist eine Anweisung zum Zeichnen (mehrerer) Dreiecke. Geben Sie als Argumente die Koordinaten des Punktes als Scheitelpunkt und die Nummer des Scheitelpunkts des Dreiecks an. Mit @pyimport importierte Funktionen übergeben Array-Argumente als numpy.array
an Python. Wenn Sie es als reguläre Liste übergeben möchten, schließen Sie es in "PyObject ()" ein.
Beachten Sie, dass Array-Indizes in Julia bei 1 beginnen, in Python bei 0. Die durch "Dreiecke" angegebene Punktnummer des Scheitelpunkts und der Array-Index in Julia werden um eins versetzt.
Hier sind einige andere Julia-Tipps.
--linspace (start, end, n)
erstellt eine Gleichheitsfolge von n
Elementen. Um die Zahlen zu bekommen. Verwenden Sie "sammeln".
--im
ist eine imaginäre Einheit.
--zeros (n)
erstellt ein Array von Float64
mit n
Elementen. Der Wert ist "0.0".
--unshift! (V, e)
fügt das Element e
am Anfang des Arrays v
hinzu. Zum Ende hinzufügen ist "push! (V, e)" oder "append! (V, e)". Das Array "v" wird in jeder Anweisung zerstört. (Es ist !
Am Ende der Anweisung)
spherical_harmonics
Portieren wir nun example_spherical_harmonics.py
auf Julia.
# phi, theta = np.mgrid[0:pi:101j, 0:2 * pi:101j]
phi = [ u1 for u1 in linspace(0,pi,101), v1 in linspace(0,2*pi,101) ]
theta = [ v1 for u1 in linspace(0,pi,101), v1 in linspace(0,2*pi,101) ]
r = 0.3
x = r * sin(phi) .* cos(theta)
y = r * sin(phi) .* sin(theta)
z = r * cos(phi)
using PyCall
@pyimport mayavi.mlab as mlab
@pyimport scipy.special as spe
mlab.figure(1, bgcolor=(1, 1, 1), fgcolor=(0,0,0), size=(400, 300))
mlab.clf()
# Represent spherical harmonics on the surface of the sphere
for n in 1:6-1, m in 0:n-1
s = real( spe.sph_harm(m, n, theta, phi) )
mlab.mesh(x - m, y - n, z, scalars=s, colormap="jet")
s[s .< 0] *= 0.97
s /= maximum(s)
mlab.mesh(s .* x - m, s .* y - n, s .* z + 1.3, scalars=s, colormap="Spectral" )
end
mlab.view(90, 70, 6.2, (-1.3, -2.9, 0.25))
mlab.show()
Ausführungsergebnis (Screenshot)
Um die Funktion der sphärischen Harmonie zu berechnen, rufen Sie in Python scipy.special.sph_harm
auf. Zeichnen Sie dann eine gekrümmte Oberfläche (Mesh).
Sie können gut zeichnen. Die Orientierungsquantenzahlen s, p, d ... der Atombahnen, die in Physik und Chemie vorkommen.
Einige Hinweise.
--numpy.mgrid
ist eine Funktion, die ein direktes Produkt aus zweidimensionalen Koordinaten oder mehr erzeugt, aber Julia hat es nicht. Aufgrund seiner Auswirkungen ist es jedoch leicht verständlich umzusetzen.
range (n)
entspricht Julias 0: n-1
. Pythons range (m, n)
entspricht Julias m: n-1
.simple structured grid
Das letzte Beispiel ist etwas knifflig. Portieren wir example_simple_structured_grid.py
nach Julia.
# x, y, z = mgrid[1:6:11j, 0:4:13j, 0:3:6j]
x = [ x1 for x1 in linspace(1.0,6.0,11), y1 in linspace(0.0,4.0,13), z1 in linspace(0.0,3.0,6) ]
y = [ y1 for x1 in linspace(1.0,6.0,11), y1 in linspace(0.0,4.0,13), z1 in linspace(0.0,3.0,6) ]
z = [ z1 for x1 in linspace(1.0,6.0,11), y1 in linspace(0.0,4.0,13), z1 in linspace(0.0,3.0,6) ]
base=x[:,:,1] + y[:,:,1]
for i in 1:size(z)[3]
z[:,:, i] = base[:,:] * 0.25 * (i-1)
end
pts=zeros(Float64, tuple(size(z)...,3))
pts[:,:,:,1] = x
pts[:,:,:,2] = y
pts[:,:,:,3] = z
scalars1 = x .* x + y .* y + z .* z
vectors1=zeros(Float64, tuple(size(z)...,3))
vectors1[:,:,:,1] = (4.0 - y * 2.0)
vectors1[:,:,:,2] = (x * 3.0 - 12.0)
vectors1[:,:,:,3] = sin(z * pi)
# pts = pts.transpose(2, 1, 0, 3).copy()
# pts= permutedims(pts, [3,2,1,4] )
# pts= reshape(pts, ( prod(size(pts)[1:3]), 3))
# vectors1= permutedims(vectors1, [3,2,1,4] )
# vectors1= reshape(vectors1, ( prod(size(vectors1)[1:3]), 3))
using PyCall
@pyimport tvtk.api as tvtk_api
# Create the dataset.vec
sg=tvtk_api.tvtk[:StructuredGrid](dimensions=size(x),points=pts)
sg[:point_data][:scalars] = vec(scalars1)
sg[:point_data][:scalars][:name] = "temperature"
sg[:point_data][:vectors] = vectors1
sg[:point_data][:vectors][:name] = "velocity"
@pyimport mayavi.mlab as mlab
d = mlab.pipeline[:add_dataset](sg)
gx = mlab.pipeline[:grid_plane](d)
gy = mlab.pipeline[:grid_plane](d)
gy[:grid_plane][:axis] = "y"
gz = mlab.pipeline[:grid_plane](d)
gz[:grid_plane][:axis] = "z"
iso = mlab.pipeline[:iso_surface](d)
iso[:contour][:maximum_contour] = 75.0
vec1 = mlab.pipeline[:vectors](d)
vec1[:glyph][:mask_input_points] = true
vec1[:glyph][:glyph][:scale_factor] = 1.5
mlab.show()
Ausführungsergebnis (Screenshot)
Python-Ausführungsergebnis (Screenshot)
Erstellen Sie ein 3D-Raster (StructuredGrid). Weisen Sie an jedem Punkt einen Skalarwert (scalar1) und einen Vektorwert (vector1) (point_data) zu. Gießen Sie dies in die Pipeline, um iso_surfaces und Vektoren zu zeichnen. Es werden auch Ebenen mit x = 0, y = 0, z = 0 (grid_plane) gezeichnet. Wenn Sie vtk Koordinatendaten geben, geben Sie ein Array an, sodass sich zuerst x, dann y und schließlich z bewegen (Spaltenmajor). Da Python-Numpy Row-Major ist, wird die Speicherreihenfolge in der ursprünglichen Python-Quelle geändert. Auf der anderen Seite ist Julia ein Kolumnenmajor, also können Sie es so lassen, wie es ist. (Referenz Zeilen-Hauptreihenfolge und Spalten-Hauptreihenfolge) Übrigens können Sie Pythons Anweisung "numpy.transpose" verwenden, um die Achsen eines mehrdimensionalen Arrays zu vertauschen. Julias "Transponieren" vertauscht nur die Zeilen und Spalten einer Matrix (zweidimensionales Array), nicht für mehrdimensionale Arrays. Verwenden Sie "permutierte", um die Achsen eines mehrdimensionalen Arrays in Julia zu vertauschen. Die folgenden zwei sind äquivalent (in Julia zählen die Achsen auch von 1):
a = a.transpose(2, 1, 0, 3).copy()
a = permutedims(a, [3,2,1,4] )
#Beim Umschreiben eines Arrays
permutedims!(a, [3,2,1,4] )
Einige Hinweise.
Die Tupelverschachtelung wird nicht erweitert. Fügen Sie zum Erweitern ...
hinzu. Es heißt Splat-Konstrukt.
julia> ((1,2),(3,4))
((1,2),(3,4))
julia> ((1,2)...,(3,4))
(1,2,(3,4))
julia> ((1,2),(3,4)...)
((1,2),3,4)
julia> ((1,2)...,(3,4)...)
(1,2,3,4)
Für ein mehrdimensionales Array "a" ist Python-numpys "a.shape" Julias "Größe (a)".
Bisher habe ich ein Beispiel für die schnelle Verwendung von Mayavi mit Julia vorgestellt. In vielen Fällen habe ich mir die Python-Quelle angesehen und gezeigt, dass sie fast mechanisch umgeschrieben werden kann. Jetzt können Sie Mayavi auch im Jupyter anzeigen. Dies wird in einem anderen Artikel vorgestellt. -> Ich habe es geschrieben. [Python, Julia] 3D-Anzeige in der Jupyter-Mayavi-Bibliothek
Recommended Posts