VectorField Element
In [1]:
import numpy as np
import holoviews as hv

A VectorField plot displays velocity vectors as arrows at x and y positions with angle and magnitude components (or alternatively U , V components). The element accepts the usual columnar format passing the (x, y, angles, magnitudes) components as a tuple, but also handles 2D arrays when supplied as a list instead:

In [2]:
%%opts VectorField [size_index=3]
x,y  = np.mgrid[-10:10,-10:10] * 0.25
sine_rings  = np.sin(x**2+y**2)*np.pi+np.pi
exp_falloff = 1/np.exp((x**2+y**2)/8)

vector_data = [x,y,sine_rings, exp_falloff]

As you can see above, here the x and y positions are chosen to make a regular grid. The arrow angles follow a sinsoidal ring pattern, and the arrow lengths fall off exponentially from the center, so this plot has four dimensions of data (direction and length for each x,y position).

Using the %%opts cell-magic, we can also use color as a redundant indicator to the direction or magnitude:

In [3]:
%%opts VectorField [size_index=3] VectorField.A [color_index=2] VectorField.M [color_index=3]
hv.VectorField(vector_data, group='A') + hv.VectorField(vector_data, group='M')

By default the arrows are rescaled to the minimum distance between individual arrows, to disable this rescaling set rescale=False and adjust the scale manually (smaller values result in larger arrows). This allows fixed scaling even when plotting arrows in an animation. Here we will vary the arrow angle with a Phase dimension and also add this angle to the magnitude data, showing the arrow angles and magnitudes varying. Due to the fixed scaling we can make out the differences across frames:

In [4]:
%%opts VectorField [color_index=2 size_index=3 rescale_lengths=False] (scale=4)
hv.HoloMap({phase: hv.VectorField([x, y,(vector_data[2]+phase)%np.pi*2, vector_data[3]+np.abs(phase)])
            for phase in np.linspace(-np.pi,np.pi,5)}, kdims=['Phase'])

Vectors are also often expressed through U and V components we can easily transform these to a magnitude and angle:

In [5]:
xs, ys = np.arange(0, 2 * np.pi, .2), np.arange(0, 2 * np.pi, .2)
X, Y = np.meshgrid(xs, ys)
U = np.cos(X)
V = np.sin(Y)

# Convert U, V to magnitude and angle
mag = np.sqrt(U**2 + V**2)
angle = (np.pi/2.) - np.arctan2(U/mag, V/mag)

VectorField also allows defining the pivot point of the vectors. We can for instance define pivot='tip' to pivot around the tip of the arrow. To make this clearer we will mark the pivot points:

In [6]:
%%opts VectorField [color_index=3 size_index=3 pivot='tip'] (cmap='fire' scale=0.8) Points (color='black' s=1)
hv.VectorField((xs, ys, angle, mag)) * hv.Points((X.flat, Y.flat))

Download this notebook from GitHub (right-click to download).