Get to Know a Feature: 3D Arrow Plots

In the previous Gizmo Plot blog posts I demonstrated some variations on the generic scatter plot and path plot.  In this blog post I’ll use the same data set to illustrate variations on a 3D arrow plot.

All arrow plots depend on the elementary arrow shape.  Gizmo draws 3D arrows as special cases of 3D lines. 

The simple arrow would initially look like the following graph:

Here I added the axis cue to show that the arrow points in the positive z-direction.
Executing the command:

ModifyGizmo enhance

would give us the following single arrow plot:

The arrow (or the supercharged line) is a regular drawing object that can be used as a marker in a scatter plot.  For example, we can draw the arrow object (instead of spheres) at the location of the data points of the Lissajous set that we used in previous blog posts.  By default the arrows are all pointing in the z-direction. 

To align the arrows with the local direction of the path we need to provide the scatter object with a rotation wave.  The rotation wave contains four numbers for each scatter point.  The first number is the rotation angle in degrees.  The last three numbers represent a normalized vector about which the object is rotated.  Here is the code I used to calculate the rotation wave:

Function makeRotationWave(pathw)
    Wave pathw      // triplet path wave

    // for a closed path the rotation wave needs to 
    // have the same rows as pathw and 4 cols.
    Variable rows=DimSize(pathw,0)
    Make/O/N=(rows,4) rotationWave
    Variable i
    Variable x1,x2,y1,y2,z1,z2
    Variable dx,dy,dz,nor,vx,vy
    for(i=0;i<rows;i+=1)
        x1=pathw[i][0]
        y1=pathw[i][1]
        z1=pathw[i][2]
        if(i==(rows-1))
            // closing the path
            x2=pathw[0][0]
            y2=pathw[0][1]
            z2=pathw[0][2]
        else
            x2=pathw[i+1][0]
            y2=pathw[i+1][1]
            z2=pathw[i+1][2]
        endif
        // desired vector direction:
        dx=x2-x1
        dy=y2-y1
        dz=z2-z1
        nor=sqrt(dx*dx+dy*dy+dz*dz)
        // normalize vector:
        dx/=nor
        dy/=nor
        dz/=nor
        // We assume a line object that points in the z-direction
        // i.e., {0,0,1}
        nor=sqrt(dy^2+dx^2)
        vx=dy/nor
        vy=-dx/nor
        rotationWave[i][1]=vx
        rotationWave[i][2]=vy
        rotationWave[i][3]=0        // it is perpendicular to z
        // the angle of rotation is computed from the dot product between the line and z
        // which is simply dz so
        rotationWave[i][0]=-180*acos(dz)/pi
    endfor
End

Once I have a rotation wave I assign it to the scatter object in the Scatter Properties dialog:

The graph now has the arrows pointing along the path:

Executing

ModifyGizmo enhance

and tweaking the direction of the light gives:

Since the arrows are extended objects one can add small spheres to designate the location of the data points.

I hope this example helps you use Gizmo more effectively.