Как построить изоповерхность сложного трехмерного поля с помощью Mayavi, избегая артефактов интерполяции цвета?
Взяв за основу пример атомной орбиты в галерее примеров, я пытаюсь визуализировать трехмерное произвольное сложное поле с помощью изоповерхности так, как циклическая палитра HSV иллюстрирует фазу поля. Однако существует проблема в точках, где фазовое поле принимает значения, близкие к и, что на следующем графике соответствует красному цвету:
В этих точках наблюдается резкий разрыв между
pi
а также
-pi
, и mayavi, кажется, интерполирует между этими значениями, и это приводит к появлению «зашумленных цветных линий» на приведенном выше графике.
Мой вопрос: есть ли способ исправить эту проблему, например, отключив интерполяцию цветов?
Код для воспроизведения сюжета:
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()
Другой способ, которым я думал решить эту проблему, - это вручную установить цвета на поверхности с помощью этой функции, которая возвращает массив цветов RGB из сложного массива 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
Однако я не знаю, есть ли встроенный метод mayavi, позволяющий прямой ввод массива с цветами RGB поверхности.
2 ответа
Проблема в вашей программе выглядит так, будто вы пытаетесь многократно n на 4, а затем показываете результат, а также 255 нельзя разделить на 4, иначе вы можете попробовать присвоить n 5 или чему-то делимому, чтобы избежать строк
Я не обнаружил ошибок в вашей программе, но я думаю, вам нужно создать поле в последовательности точно так же, как field (1) field(2) field(3), а затем запустить программу:
print(field(1))
print(field(2))
и так далее.
Вы также должны попробовать это в верхней части программы записи поля.
import numpy as a np
from mayavi import mlab
𝜇 =
σ =
V =
density =
phi =
density =