2017-06-28 2 views
1

Ich versuche, ein Vektorfeld zu plotten, und ich benutze Mayavi2s quiver3d() -Funktion. Ich würde die Pfeile wie auf dem Einheitskugel farblich nach ihrem Winkel zu:Colormap für quiver3d() in Mayavi

enter image description here

ich diesen auf diese Weise tun:

def color(theta, phi): 
    while(phi < 0): 
     phi += 2.0*np.pi 
    h = phi/(2.0 * np.pi) 
    s = 1 
    v = 1.0 - 0.9999999*(theta/np.pi) 
    print("h = {}, s = {}, v ={}".format(h,s,v)) 
    return hsv_to_rgb(h,s,v) 

def plot_nice(): 
    x = np.array([1.,2.,3.]) 
    y = np.array([0.,0.,0.]) 
    z = y 

    phi = np.linspace(0,np.pi/2.0,3) 
    theta = phi 

    u = np.sin(theta) * np.cos(phi) 
    v = np.sin(theta) * np.sin(phi) 
    w = np.cos(theta) 

    obj = quiver3d(x, y, z, u, v, w, 
      line_width=3, colormap='hsv', 
      scale_factor=0.8, mode='arrow',resolution=25) 

    for i in range(x.shape[0]): 
     r,g,b = color(theta[i], phi[i]) 
     print("R: {}, G: {}, B: {}".format(r,g,b)) 
     obj = quiver3d(x[i], y[i], z[i], u[i], v[i], w[i], 
       line_width=3, color=(r,g,b), colormap='hsv', 
       scale_factor=0.8, mode='arrow',resolution=25) 
    return obj 

figure(bgcolor=(1,1,1)) 
plot_nice() 

Aber das ist sehr langsam, wenn ich Hunderte von Pfeilen. Ich kann es in einem schnelleren Weg tun:

def plot_fast(): 
    x = np.array([1.,2.,3.]) 
    y = np.array([0.,0.,0.]) 
    z = y 

    phi = np.linspace(0,np.pi/2.0,3) 
    theta = phi 

    u = np.sin(theta) * np.cos(phi) 
    v = np.sin(theta) * np.sin(phi) 
    w = np.cos(theta) 

    obj = quiver3d(x, y, z, u, v, w, 
      line_width=3, colormap='hsv', 
      scale_factor=0.8, mode='arrow',resolution=25) 
plot_fast() 

Aber ich locker die colormap: enter image description here

Wie kann ich so etwas wie die obere Kurve erstellen, ohne ein neues Grundstück für jeden Pfeil erstellen zu müssen?

Antwort

0

Es ist möglich, das Plot-Objekt nachträglich zu manipulieren.

Zum Aufruf quiver3d die Argumente scalars=np.mod(phi, 2*np.pi) (zum Beispiel) und scale_mode='none' hinzufügen. Nach dem Aufruf fügen Sie die Zeile

obj.glyph.color_mode = 'color_by_scalar' 

Aus dem Gedächtnis, könnte es möglich sein, separat die Farbe und die Größe der Pfeile zu kontrollieren, aber das ist ein bisschen komplizierter.

+0

Wenn ich Sie richtig verstanden Krieg, dann kann ich nur eindimensionale Informationen kodieren, richtig? Ich möchte sowohl den Polarwinkel als auch den Azimutwinkel kodieren. Z.B. so: https://en.wikipedia.org/wiki/HSL_and_HSV – Stein

+0

Sie können entweder eine benutzerdefinierte Länge oder eine benutzerdefinierte Farbe haben. Die Farbe kann abhängig von Phi und Theta in welcher Art auch immer Sie wählen. Das Skalarargument muss die gleiche Länge wie x, y, z, u, v und w haben, das ist alles. –