网格图上的径向颜色图

时间:2019-06-18 22:29:53

标签: python mayavi

我正在尝试绘制带有径向色图的网格。也就是说,我希望半径恒定的所有点都具有相同的颜色。

我尝试了this example,但这使我只能在z方向上修改颜色,而不能在三个坐标上进行修改。

任何帮助将不胜感激。 谢谢。

修改

这是代码。计算天线阵列的解阵列系数

from AntennaArray2 import *
from mayavi import mlab

a = AntennaArray(5.8e9,[1,4],'uniform') #creates an array of antennas object

op = 1  #opacity of the plot

a.move_array([-a.dx*1.5,0,0])   #moves the elements of the array, centering them in (0,0,0)

fig = mlab.figure(bgcolor=(1,1,1))

phases1 = array([109.77, 9.639, -85.92, -174.355])      #phases of the array elements
phases2 = array([-167.8, 149.42, 115.28, 102.74])
phases1*= pi/180
phases2*= pi/180

a.set_element_phase(phases1)    #steers the array for the given elements phases

x,y,z = a.plot_array_factor_3d()    #calculates the array factor of the array. 


mesh = mlab.mesh(x,y,z,opacity=op)

mlab.show()

在给定球形(r,theta,phi)的情况下,plot_array_factor_3d()给出(x,y,z)(theta和phi是numpy.mgrid [],r是数组因子)。

我想要放射状的颜色图,以便可以代表阵列系数的大小。

此代码给出以下输出: array factor 如您所见,这些颜色不能代表磁场强度。

谢谢!

修改2

from numpy import *
import warnings
class AntennaArray:
    def __init__(self,f,size=None,tipo=None,dx=None,dy=None):
        self.Lambda = 299792458 / f
        self.k = 2*pi/self.Lambda
        self.size = size
        self.type = tipo
        self._AF_DATA_SIZE = 200
        self.theta,self.phi =  mgrid[0 : 2*pi : self._AF_DATA_SIZE*1j,0 : pi : self._AF_DATA_SIZE*1j]
        self.antenna_array = None

        if dx == None:
            self.dx = self.Lambda/2
        else:
            self.dx = dx

        if dy == None:
            self.dy = self.Lambda/2
        else:
            self.dy = dy

        if tipo is not None:
            self.generate_array(tipo,size[0],size[1],self.dx,self.dy)

        if self.antenna_array is not None:
            self.array_factor = self.calculate_array_factor()

        self.antennaField = 1

    def generate_array(self,tipo,*args):
        """generate_array
        Genera una matriz que contiene la informacion del array.
        Columna 1: posiciones x de los elementos
        Columna 2: posiciones y de los elementos
        Columna 3: posiciones z de los elementos
        Columna 4: amplitudes de los elementos
        Columna 5: fase relativa de cada elemento.


        Ejemplo: array uniforme de 4x1 (4 elementos sobre el eje x)
        [[0, 0, 0,  1,  0],        z
         [1, 0, 0,  1,  0],        |
         [2, 0, 0,  1,  0],        |      <dx>
         [3, 0, 0,  1,  0]]        |O____O____O____O______
                                    0    1    2    3       x

        @ Argumentos
        Tipo: 
        + uniform: genera array uniforme de MxN (todos los pesos 1, las fases 0)
        args = (M,N,dx,dy)

        + difference: genera un array de MxN, todos los pesos -1 hasta la mitad de los elementos y luego +1.
        todas las fases son 0.
        args = (M,N,dx,dy)

        + matrix: recibe como argumento una matriz (numpy.array()) de MxN. En donde hay un numero en la matriz distinto de 0
        coloca un elemento ahi, cuya amplitud y fase es el valor en la poscion de la matriz.
        El segundo argumento son las distancias dx y dy.
        args = (ARRAY,dx,dy)

        @ Return
        antenna_array: numpy.array() (MxN x 5) que contiene la informacion del arreglo.
        """
        if tipo == 'uniform':

            M = args[0]
            N = args[1]
            dx = args[2]
            dy = args[3]

            self.size = [M,N]
            x_pos = arange(0,dx*N,dx)
            y_pos = arange(0,dy*M,dy)
            z_pos = 0

            ele = zeros([N*M,5])

            for i in range(M):
                ele[i*N:(i+1)*N,0] = x_pos[:]#x_pos[i] 


            for i in range(M):
                ele[i*N:(i+1)*N,1] = y_pos[i]

            ele[:,3]=1

            self.antenna_array = ele

        if tipo == 'difference':

            M = args[0]
            N = args[1]
            dx = args[2]
            dy = args[3]

            self.size = [M,N]
            x_pos = arange(0,dx*N,dx)
            y_pos = arange(0,dy*M,dy)
            z_pos = 0

            ele = zeros([N*M,5])

            for i in range(M):
                ele[i*N:(i+1)*N,0] = x_pos[:]#x_pos[i] 


            for i in range(M):
                ele[i*N:(i+1)*N,1] = y_pos[i]

            ele[:,3]=1

            self.antenna_array = ele

        if tipo == 'matrix':
            x = args[0]

            if (size(x.shape) > 1):
                if (x.shape[1] > 1) :  
                    dy = args[2]

            if (x.shape[0] is not None) or (x.shape[1] > 1):   
                dx = args[1]

            M = x.shape[0]
            if size(x.shape) > 1:
                N = x.shape[1]
            else:
                N = 1

            self.size = [M,N]
            ele = zeros([M*N,5])

            ele[:,0] = where(x!=0)[0]*self.dx
            if (size(x.shape) > 1):
                ele[:,1] = where(x!=0)[1]*self.dy
            else:
                ele[:,1] = 0
            ele[:,2] = 0
            ele[:,3] = x[where(x!=0)]  
            ele[:,4] = 0

            self.antenna_array = ele

            self.array_factor = self.calculate_array_factor()

    def calculate_array_factor(self):
        '''No llamar esta funcion
        ''' 

        theta,phi = self.theta,self.phi

        k = self.k

        x_pos = self.antenna_array[:,0]
        y_pos = self.antenna_array[:,1]
        z_pos = self.antenna_array[:,2]

        w = self.antenna_array[:,3]*exp(1j*self.antenna_array[:,4])

        af = zeros([theta.shape[0],phi.shape[0]])

        for i in range(self.antenna_array.shape[0]):
            af = af + ( w[i]*e**(-1j*(k * x_pos[i]*sin(theta)*cos(phi) + k * y_pos[i]* sin(theta)*sin(phi)+ k * z_pos[i] * cos(theta))) )

        return af

    def set_antenna_field(self,antennaFarfield):
        '''Asigna el patron de la antena de cada elemento del array.
        Cuando esta funcion es llamada, recalcula el patron de antena.
        Si el tamanio de antennaFarfield es distinto del tamanio de array_factor, entonces
        re-calcula el factor de arreglo de manera que tengan el mismo tamanio

        @ Argumentos
            antennaFarfield: numpy.array que contiene los valores del campo de la antena
            en coordenadas esfericas.
        '''

        self.antennaField = antennaFarfield
        if antennaFarfield.shape[0] != self.array_factor.shape[0]:
            self._AF_DATA_SIZE = antennaFarfield.shape[0]
            self.array_factor,_,__ = self.calculate_array_factor()
        self.antennaFactor = self.array_factor * self.antennaField

    def set_element_phase(self,phase):
        warnings.warn('La fase va por filas. Cuidado con los arrays planares.')
        M,N = self.size[0],self.size[1]
        for i in range(M*N):
            self.antenna_array[i,4] = phase[i]

        self.array_factor = self.calculate_array_factor()
        return

    def plot_array_factor_3d(self):
        '''Devuelve el factor de array en x,y,z.
        Para plotear, utilizar la funcion mlab.mesh(x,y,z) de 
        mayavi. La cantidad de puntos (tamanio de x y z) depende de 
        DATA_SIZE de la funcion Antennaantenna_array().
        '''
        af = self.array_factor
        theta,phi = self.theta,self.phi
        r = abs(af)
        x = r * sin(theta) * cos(phi)
        y = r * sin(theta) * sin(phi)
        z = r * cos(theta)
        return x,y,z

    def plot_antenna_field_3d(self):
        '''Devuelve el campo de antena en x,y,z.
        Para plotear, utilizar la funcion mlab.mesh(x,y,z) de 
        mayavi. La cantidad de puntos (tamanio de x y z) depende de 
        DATA_SIZE de la funcion Antennaantenna_array().
        '''
        af= self.antennaField
        theta,phi = self.theta,self.phi
        r = abs(af)
        x = r * sin(theta) * cos(phi)
        y = r * sin(theta) * sin(phi)
        z = r * cos(theta)
        return x,y,z

    def plot_antenna_factor_3d(self):
        '''Devuelve el factor de antena  en x,y,z.
        Para plotear, utilizar la funcion mlab.mesh(x,y,z) de 
        mayavi. La cantidad de puntos (tamanio de x y z) depende de 
        DATA_SIZE de la funcion Antennaantenna_array().
        Nota: FactorAntenna = Factorantenna_array x CampoAntenna
        '''
        af= self.antennaFactor
        theta,phi = self.theta,self.phi
        r = abs(af)
        x = r * sin(theta) * cos(phi)
        y = r * sin(theta) * sin(phi)
        z = r * cos(theta)
        return x,y,z

    def move_array(self,pos):
        """Mueve el arreglo de antenas y actualiza el antenna_array factor.

        @ Argumentos:
            pos: tuple, list o numpy.array(). Contiene la posicion en X, en Y y en Z.
        """
        pos_x = pos[0]
        pos_y = pos[1]
        pos_z = pos[2]
        self.antenna_array[:,0] += pos_x
        self.antenna_array[:,1] += pos_y
        self.antenna_array[:,2] += pos_z
        self.array_factor = self.calculate_array_factor()

    def steer_array(self,theta_s,phi_s):
        '''Desfasa cada elemento del arreglo para hacer que este apunte en la direccion
        de theta_s y phi_s (azimuth y angulo de elevacion).

        @ Argumentos:
            theta_s,phi_s: angulo de elevacion y de azimuth respectivamente en radianes.
        '''

        M = self.size[0]
        N = self.size[1]

        x_pos = self.antenna_array[:,0]
        y_pos = self.antenna_array[:,1]
        z_pos = self.antenna_array[:,2]

        for i in range(M*N):
            self.antenna_array[i,4]= self.k*(x_pos[i]*sin(theta_s)*cos(phi_s)+y_pos[i]*sin(theta_s)*sin(phi_s)+z_pos[i]*cos(theta_s))
        self.array_factor = self.calculate_array_factor()

    def plot_array(self):
        '''
        Muestra como estan distribuidos los elementos del array en el espacio.
        @ Return:
            x,y: puntos donde estan los elementos del array.
        ''' 
        x = zeros(self.antenna_array.shape[0])
        y = zeros(self.antenna_array.shape[0])
        for i in range(self.antenna_array.shape[0]):
            x[i] = self.antenna_array[i,0]/self.Lambda
            y[i] = self.antenna_array[i,1]/self.Lambda
        return x,y

    def plot_array_factor_2d(self,theta_p = None, phi_p = None):
        '''Devuelve AF(theta,phi=phi_p) o AF(theta=theta_p,phi)
        segun corresponda. Si theta_p es no None, phi_p debe ser
        None, sino se retorna error.

        @ Argumentos:
            theta_p: angulo theta que se quiere observar.
            phi_p:   angulo phi que se quiere observar.

        @ Return
            x,y:  datos para plotear el grafico en 2D. devuelve 0,0 si
            theta_p y phi_p son distintos de None.

        '''
#         af = self.array_factor
#         theta,phi = self.theta,self.phi
#         r = abs(af)
#         x = r * sin(theta) * cos(phi)
#         y = r * sin(theta) * sin(phi)
#         z = r * cos(theta)

#         rot_azimuth = array([
#             [cos(phi_p),-sin(phi_p),0],
#             [sin(phi_p), cos(phi_p),0],
#             [0         , 0         ,1]
#         ])


#         rot_zenith = array([
#             [1           ,0        ,0],
#             [0,cos(phi_p),-sin(phi_p)],
#             [0,sin(phi_p), cos(phi_p)]
#         ])




#         if theta_p is None:
#             af2d = self.array_factor[]

1 个答案:

答案 0 :(得分:2)

我找到了替换解决方案

mesh = mlab.mesh(x,y,z,opacity=op)

使用

x = x.flatten()
y = y.flatten()
z = z.flatten()

s = sqrt( x**2 + y**2 + z**2)

mlab.points3d(x,y,z,s)

这给出了放射状的颜色图

result

谢谢!

修改2

只需要在mlab.mesh(x,y,z,scalars=s)上添加标量

对不起,谢谢。