[Attention] Cet article a été publié en décembre 2016. Le code ci-dessous est pour Julia 0.6.
Calendrier de l'Avent Julia 2016 C'est l'article du 6ème jour.
Essayons d'utiliser une bibliothèque appelée MayaVi de Julia, qui a récemment été fournie avec un package conda.
MayaVi est un package pour les tracés 3D. Le plan est comme suit.
Une bibliothèque avec un caractère similaire est ParaView (http://www.paraview.org). Ceci vise une décentralisation parallèle et est probablement plus célèbre que MayaVi. J'ai commencé à utiliser MayaVi et j'ai eu beaucoup de mal à installer ParaView. La convivialité est similaire et MayaVi est recommandée pour les projets personnels.
La gestion des paquets conda dans Julia a été expliquée dans l'article d'hier. (Ajouter un package conda de Julia)
Utilisez Conda.add ()
pour ajouter le paquet mayavi à l'environnement miniconda installé par Julia.
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:
...Ce qui suit est omis.
Si vous souhaitez ajouter mayavi à votre propre environnement anaconda, vous pouvez lancer la commande conda à partir du shell (ligne de commande, terminal).
$ 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:
...Ce qui suit est omis.
MayaVi functions gallery
Commencez par essayer l'exemple de la Galerie des fonctions MayaVi.
julia> using PyCall
julia> @pyimport mayavi.mlab as mlab
julia> mlab.test_plot3d()
PyObject <mayavi.modules.glyph.Glyph object at 0x337fc95f0>
julia> mlab.show()
Fichier source ci-dessus: plot3d () https://gist.github.com/d4578e1f4d22bbfa0f418f0caff239c7
Résultat de l'exécution (capture d'écran)
mayavi.mlab
est un outil pour tracer simplement numpy.array
de Python. Si vous connaissez matplotlib
, pouvez-vous deviner qu'il correspond à matplotlib.pyplot
?
Lorsque vous démarrez mlab.show ()
, le dessin réel sera fait. En haut du tracé 3D, il y a une barre de menus avec plusieurs icônes, qui vous permet de faire pivoter et de mettre à l'échelle la figure. La fonctionnalité ici s'appelle «traits» (aucune bonne traduction trouvée).
Désormais, les huit autres exemples de la galerie Mayavi Functions ont également été affichés avec succès. Mettez le fichier source dans gist. --Points (sphère) points3d (): https://gist.github.com/a3b0b95b58a42b7b010aea779536e6f3 --Image imshow (): https://gist.github.com/326f9b72a56f6187f0d62b7e9e3ca4ed
Résultat d'exécution de test_mesh () (capture d'écran)
surface_from_irregular_data
Vous trouverez ci-dessous quatre exemples de programmes qui fournissent des astuces et des astuces connexes pour le portage de programmes Mayavi en Python vers Julia.
C'est un programme appelé 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()
Résultat de l'exécution (capture d'écran)
Étendez un point bidimensionnel irrégulier (x, y)
à un point tridimensionnel (x, y, z)
en utilisant la fonction z = f (x, y)
. Dessinez-les sous forme de points (sphères) (points3d). Il interpole également les points 3D (delaunay2d) et dessine sa surface (surf). Le processus d'ajout d'un traitement aux données s'appelle un pipeline.
La source Julia est presque la même que la source Python. J'ai prêté attention aux points suivants.
mlab.pipeline.delaunay2d
etc. de Python ne peut pas être appelé tel quel, maismlab.pipeline [: delaunay2d] ʻetc. --Dans
function, correction de la puissance de chaque élément à
. ^`.triangular_mesh
Ensuite, essayez de porter le programme à l'intérieur de test_triangular_mesh
vers Julia.
# 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()
Résultat de l'exécution (capture d'écran) * La figure est réduite / pivotée:
mlab.triangular_mesh
est une instruction pour dessiner (plusieurs) triangles. En argument, donnez les coordonnées du point qui sera le sommet et le numéro du sommet du triangle. Les fonctions importées avec @pyimport transmettent des arguments de tableau à Python en tant que numpy.array
. Si vous voulez le passer comme une liste régulière, enveloppez-le dans PyObject ()
.
Notez que les indices de tableau commencent à 1 dans Julia, contre 0 en Python. Le numéro de point du sommet indiqué par «triangles» et l'indice du tableau dans Julia seront décalés de un.
Voici quelques autres conseils de Julia.
--linspace (start, end, n)
crée une séquence d'égalité de n
éléments. Pour obtenir les chiffres. Utilisez «collect».
--ʻIm est une unité imaginaire. --
zeros (n) crée un tableau de
Float64 avec des éléments
n. La valeur est "0.0". --ʻUnshift! (V, e)
ajoute l'élément ʻe au début du tableau
v. Ajouter à la fin est
push! (V, e)ou ʻappend! (V, e)
. Le tableau «v» est détruit dans n'importe quelle instruction. (C'est «!» À la fin de l'instruction)
spherical_harmonics
Portons maintenant ʻexample_spherical_harmonics.py` vers 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()
Résultat de l'exécution (capture d'écran)
Pour calculer la fonction d'harmonie sphérique, appelez scipy.special.sph_harm
en Python. Ensuite, dessinez une surface courbe (maillage).
Vous pouvez bien dessiner. Les nombres quantiques d'orientation s, p, d ... des orbites atomiques qui apparaissent en physique et en chimie.
Quelques conseils.
--numpy.mgrid
est une fonction qui crée un produit direct de coordonnées bidimensionnelles ou plus, mais Julia ne l'a pas. Cependant, compte tenu de ses implications, il est facile à mettre en œuvre avec compréhension.
simple structured grid
Le dernier exemple est un peu délicat. Portons ʻexample_simple_structured_grid.py` sur Julia.
--Source Python: http://docs.enthought.com/mayavi/mayavi/auto/example_simple_structured_grid.html#example-simple-structured-grid
# 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()
Résultat de l'exécution (capture d'écran)
Résultat d'exécution Python (capture d'écran)
Créez une grille 3D (StructuredGrid). À chaque point, attribuez une valeur scalaire (scalaire1) et une valeur vectorielle (vector1) (point_data). Versez ceci dans le pipeline pour dessiner des iso_surfaces et des vecteurs. Il dessine également des plans avec x = 0, y = 0, z = 0 (grid_plane).
Lorsque vous donnez des coordonnées à vtk, donnez un tableau de sorte que x d'abord, puis y et enfin z se déplacent (colonne principale). Étant donné que python-numpy est une ligne majeure, l'ordre de stockage est modifié dans la source python d'origine. D'un autre côté, Julia est une colonne majeure, vous pouvez donc la laisser telle quelle. (Référence Ordre principal des lignes et Ordre des colonnes principales)
En passant, vous pouvez utiliser l'instruction numpy.transpose
de Python pour permuter les axes d'un tableau multidimensionnel. La «transposition» de Julia n'échange que les lignes et les colonnes d'une matrice (tableau à deux dimensions), pas pour les tableaux multidimensionnels. Utilisez permutedims
pour permuter les axes d'un tableau multidimensionnel dans Julia. Les deux suivants sont équivalents (chez Julia, les axes comptent également à partir de 1):
a = a.transpose(2, 1, 0, 3).copy()
a = permutedims(a, [3,2,1,4] )
#Lors de la réécriture d'un tableau
permutedims!(a, [3,2,1,4] )
Quelques conseils.
L'imbrication de tuples n'est pas étendue. Ajoutez ...
pour développer. C'est ce qu'on appelle la construction splat.
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)
Pour un tableau multidimensionnel ʻa, ʻa.shape
de Python-numpy est la taille (a)
de Julia.
Jusqu'à présent, j'ai présenté un exemple d'utilisation de Mayavi avec Julia à la hâte. Dans de nombreux cas, j'ai regardé la source Python et montré qu'elle pouvait être réécrite presque mécaniquement. Maintenant, vous pouvez également voir Mayavi à l'intérieur du Jupyter. Cela sera présenté dans un autre article. -> Je l'ai écrit. [Python, Julia] Affichage 3D dans Jupyter - Bibliothèque Mayavi
Recommended Posts