Eli S Eli S - 29 days ago 14
Python Question

Coordinating basemap quiver and matplotlib arrow

I am trying to compare vectors of wind in matplotlib between gridded model output locations (via quiver on a basemap map) and scattered stations (via matplotlib arrow). The locations for both are in lat/lon, but wind vectors are in m/s.

When combined, I want the colors and lengths to vary by magnitude and for both qualities to be scaled the same way for the quiver and arrow data. I have given an example below where the quiver plot looks OK and is scaled in absolute length (inches). I don't know what to do to for arrow() to match. In the example I've divided it by SCALE to give a sense of what I'd like the final image to look like.

import numpy as np
import matplotlib.pylab as plt
from mpl_toolkits.basemap import Basemap

X, Y = np.meshgrid(np.arange(-123,-121,0.3),np.arange(37,39,0.3))
U = np.cos(X+123)*12
V = np.sin(Y-37)*12
mag = np.hypot(U,V)

fig,ax=plt.subplots(1)
m=Basemap(projection ='cyl',resolution='f',llcrnrlat=37,llcrnrlon=-123,
urcrnrlat=39,urcrnrlon=-121,ax=ax)

quiv = m.quiver(X,Y,U,V,mag,zorder=2,latlon=True,scale=30,scale_units='inches')

# Scattered points won't be on the grid
x0=X[2,2] - 0.025
y0=Y[2,2]

u0=U[2,2]
v0=V[2,2] + 0.5
SCALE = 72.
plt.arrow(x0,y0,u0/SCALE,v0/SCALE)

plt.show()

Answer

It's not terribly clear from the matplotlib documentation (in my opinion), but quiver does accept 1D arrays for all of X, Y, U and V, which do not need to be uniformly spaced. The basemap documentation gets that wrong, or is at least even more unclear. So as long as you form your scattered stations data into 1D arrays, you should be fine.

I added some random arrows to your plot by replacing your scattered points section with this (if you use the same seed you should get the same arrows):

# Make scattered locations
np.random.seed(33)
x0 = np.random.rand(5)*2.0 - 123
y0 = np.random.rand(5)*2.0 + 37

# Make some velocities
u0 = np.random.randn(5)*3 + 10
v0 = np.random.randn(5)*3 + 10

q2 = m.quiver(x0, y0, u0, v0, latlon=True, scale=30, scale_units='inches')

And this is the plot that I get (I use the YlGnBu_r colormap by default). regular grid plus scattered locations

Be aware that if you start to use anything other than a cylindrical-type projection (and if your U and V are expressed in east-west and north-south) you will need to rotate the vectors to match the projection using the rotate_vector method.

Comments