enthought / enthought/mayavi

Problem with the visualization of an isosurface of a 3D complex field.

Open
#1,056 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
1.4k
Forks
316
Avg merge
7h 44m
Merged PRs (30d)
5

Description

Taking as a basis the [Atomic orbital example](https://docs.enthought.com/mayavi/mayavi/auto/example_atomic_orbital.html) 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:
![snapshot](https://user-images.githubusercontent.com/37953893/124393077-01cb4c00-dcf9-11eb-8bad-725856ed8907.png)

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 plot from above.

**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.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.