Taking as a basis the Atomic orbital example in the example gallery, I'm trying to visualize a 3D arbitrary complex field using an isosurface, in the way the cyclic HSV colormap illustrates the phase of the field. However, there is a problem in the points where the phase-field takes values near pi
and -pi
, which in the following plot, corresponds to the red color:
In these points, there is a sharp discontinuity between pi
and -pi
, and mayavi seems to be interpolating between these values, and this results in "noisy color lines" that appear in the above plot.
My question, is there a way to fix this problem? (for example by disabling the color interpolation)
Code to reproduce the plot:
import numpy as np
from mayavi import mlab
L = 1.0
N = 150
xx, yy, zz = np.mgrid[-L:L:N*1j, -L:L:N*1j, -L:L:N*1j]
𝜇 = 0.0
σ = 0.30
V = np.exp((-(xx-𝜇)**2 -(yy)**2 -(zz)**2 ) / (2*σ**2))
density = V/np.amax(np.abs(V))
phi = np.arctan2(yy,xx)
density = density *np.exp(6*phi*1j)
figure = mlab.figure('Phase Plot',bgcolor=(0, 0, 0), size=(700, 700))
field = mlab.pipeline.scalar_field(np.abs(density),vmin= 0.0 ,vmax= 1.0)
colour_data = (np.angle(density.T.ravel()))
field.image_data.point_data.add_array(colour_data)
field.image_data.point_data.get_array(1).name = 'phase'
field.update()
field2 = mlab.pipeline.set_active_attribute(field, point_scalars='scalar')
contour = mlab.pipeline.contour(field2)
contour.filter.contours= [0.1,]
contour2 = mlab.pipeline.set_active_attribute(contour,
point_scalars='phase')
mlab.pipeline.surface(contour2, colormap='hsv', vmin= -np.pi ,vmax= np.pi)
mlab.colorbar(title='Phase', orientation='vertical', nb_labels=3)
φ = 30
mlab.view(azimuth= φ, distance = N*4)
mlab.show()
Another way I was thinking to solve this problem is by manually setting the colors on the surface using this function, which returns an array of RGB colors from a complex array Z:
from matplotlib.colors import hsv_to_rgb
import numpy as np
def complex_to_rgb(Z):
r = np.abs(Z)
arg = np.angle(Z)
h = (arg + np.pi) / (2 * np.pi)
s = np.ones(h.shape)
v = r / np.amax(r) #alpha
c = hsv_to_rgb( np.moveaxis(np.array([h,s,v]) , 0, -1) ) # --> tuple
return c
However, I don't know if there is a mayavi inbuilt method to allow direct input of an array with the RGB colors of the surface.
from How to plot an isosurface of a 3D complex field with Mayavi avoiding color interpolation artifacts?
No comments:
Post a Comment