4

假设我们有一些 3D值函数 f(x,y,z)。使用 Plotly,我试图绘制大小的等值面 |f(x,y,z)| 的这种功能。到目前为止,一切正常,我的代码似乎运行良好,请在下面找到有关原子轨道函数的工作示例:

import chart_studio.plotly as py
import plotly.graph_objs as go
import scipy.special as scispe
import numpy as np
import math

a=5.29e-11          # Bohr radius (m)

def orbital(n,l,m,r,theta,phi):         # Complex function I want to plot
    L=scispe.genlaguerre(n-l-1,2*l+1)   # Laguerre polynomial
    radial= (2/(n*a))**(3/2) * np.sqrt(math.factorial(n-l-1)/(2*n*math.factorial(n+l))) * np.exp(-2*r/n) * (2*r/n)**l * L(2*r/n)
    wavefunction = radial * scispe.sph_harm(m,l, phi, theta)
    return wavefunction

#Quantum numbers
n=2
l=1
m=0

goodspan = (3 * n**2 - l * (l+1))/2   #Plot span adpated to the mean electron position
x, y, z = np.mgrid[-goodspan:goodspan:40j, -goodspan:goodspan:40j, -goodspan:goodspan:40j]    #in units of a
r = np.sqrt(x**2 + y**2 + z**2)    #Function has to be evaluated in spherical coordinates
theta = np.arccos(z/r)
phi = np.arctan(y/x)

AO=orbital(n,l,m,r,theta,phi)

magnitude = abs(AO)         # Compute the magnitude of the function
phase = np.angle(AO)        # Compute the phase of the function

isoprob = np.amax(magnitude)/2    # Set value the isosurface

fig = go.Figure(data=go.Isosurface(
    x=x.flatten(),
    y=y.flatten(),
    z=z.flatten(),
    value=magnitude.flatten(),
    opacity=0.5,
    isomin=isoprob,
    isomax=isoprob,
    surface_count=1,
    caps=dict(x_show=True, y_show=True)
    ))
fig.show()

这给了我这个: 在此处输入图像描述

此时,图形的色标取决于幅值|f(x,y,z)|的值,因此单个等值面的颜色始终是均匀的。

现在,为了将色标映射到幅度 |f(x,y,z)|,我希望它映射到相位Ф(x,y,z) = arg(f(x ,y,z)),因此绘制的等值面的每个点的颜色告诉我们字段 Ф(x,y,z) 的值(理想情况下分布在 [-π,π] 上)而不是|f(x,y,z)| 在这一点。

基本上,如果可能的话,我想用 Plotly 而不是 Mayavi来做这件事。

在我看来,所有这些都与设置函数的cmincmax参数的特殊方式有关Isosurface,但我不知道如何做到这一点。

4

2 回答 2

1

正如@gnodab 在他的评论中提到的那样,绘图等值面并不真正支持按第五维为表面着色(至少没有明显的方法可以做到这一点)。我也不确定是否可以提取描述等值面的数据以某种方式重新绘制为常规表面。

然而,在这篇文章中,他们描述了如何生成一个等值面,skimage.measure.marching_cubes_lewiner然后使用该等值面通过自定义色标进行绘制和着色,并将 plotly 作为'mesh3d'跟踪。这可能是你想要的。如果我有时间,我会尝试一下,稍后再编辑我的答案。

于 2020-05-24T13:02:43.243 回答
1

鉴于@Jan Joswig 的回答和他们提供的链接,快速/紧凑的做法是:

import plotly.graph_objects as go
from skimage import measure
import numpy as np
xyz_shape = vol.shape
verts, faces = measure.marching_cubes(vol, .5)[:2] # iso-surface at .5 level

x, y, z = verts.T
I, J, K = faces.T

fig = go.Figure(
    data=[go.Mesh3d(
        x=x,
        y=y,
        z=z,
        color='lightpink',
        opacity=0.50,
        i=I,
        j=J,
        k=K, )])
fig.show()
于 2021-04-13T21:12:55.520 回答