Jeff,
I made minimal changes to my copy of basemap to support the new quiver
and quiverkey, and to illustrate them in quiver_demo.py. The older
quiver is still accessible as quiver_classic. A diff against svn is
attached. (It includes do-nothing diffs caused by my editor's deletion
of end-of-line whitespace when a file is saved.) If you like, I can
commit the changes.
There is still what I hope is a minor flaw: when the aspect ratio is
controlled, as in basemap, it seems that the changes in rendered arrow
width upon zooming are a bit jumpy, and the key arrow width can end up a
bit different from the map arrow widths. I don't think this affects the
length, so the key is still valid (as far as I have been able to
determine.) I would like to improve this, but I don't think that use of
the new quiver needs to wait for it.
Eric
Index: lib/matplotlib/toolkits/basemap/basemap.py
===================================================================
--- lib/matplotlib/toolkits/basemap/basemap.py (revision 2450)
+++ lib/matplotlib/toolkits/basemap/basemap.py (working copy)
@@ -44,7 +44,7 @@
(cylindrical equidistant, mercator, polyconic, oblique mercator,
transverse mercator, miller cylindrical, lambert conformal conic,
azimuthal equidistant, equidistant conic, lambert azimuthal equal area,
- albers equal area conic, gnomonic, orthographic, sinusoidal, mollweide,
+ albers equal area conic, gnomonic, orthographic, sinusoidal, mollweide,
robinson, cassini-soldner or stereographic).
Doesn't actually draw anything, but sets up the map projection class and
creates the coastline, lake river and political boundary data
@@ -54,7 +54,7 @@
Useful instance variables:
projection - map projection ('cyl','merc','mill','lcc','eqdc','aea',
- 'laea', 'nplaea', 'splaea', 'tmerc', 'omerc', 'cass', 'gnom', 'poly',
+ 'laea', 'nplaea', 'splaea', 'tmerc', 'omerc', 'cass', 'gnom', 'poly',
'sinu', 'moll', 'ortho', 'robin', 'aeqd', 'npaeqd', 'spaeqd', 'stere',
'npstere' or 'spstere')
(projections prefixed with 'np' or 'sp' are special case polar-centric
@@ -68,7 +68,7 @@
rmajor,rminor - equatorial and polar radii of ellipsoid used (in meters).
resolution - resolution of boundary dataset being used ('c' for crude,
'l' for low, etc.). If None, no boundary dataset is associated with the
- Basemap instance.
+ Basemap instance.
Example Usage:
@@ -135,7 +135,7 @@
If the orthographic, sinusoidal, mollweide, npstere, spstere, nplaea, splaea,
nplaea, splaea, npaeqd, spaeqd or robinson projection is chosen
the values of llcrnrlon,llcrnrlat,urcrnrlon and urcrnrlat are ignored
- (because either they are computed internally, or entire globe is
+ (because either they are computed internally, or entire globe is
always plotted).
resolution - resolution of boundary database to use. Can be 'c' (crude),
@@ -1151,7 +1151,7 @@
After filling continents, lakes are re-filled with axis background color.
"""
if self.resolution is None:
- raise AttributeError, 'there are no boundary datasets associated with this Basemap instance'
+ raise AttributeError, 'there are no boundary datasets associated with this Basemap instance'
# get current axes instance (if none specified).
if ax is None and self.ax is None:
try:
@@ -1202,7 +1202,7 @@
ax - axes instance (overrides default axes instance)
"""
if self.resolution is None:
- raise AttributeError, 'there are no boundary datasets associated with this Basemap instance'
+ raise AttributeError, 'there are no boundary datasets associated with this Basemap instance'
# get current axes instance (if none specified).
if ax is None and self.ax is None:
try:
@@ -1233,7 +1233,7 @@
ax - axes instance (overrides default axes instance)
"""
if self.resolution is None:
- raise AttributeError, 'there are no boundary datasets associated with this Basemap instance'
+ raise AttributeError, 'there are no boundary datasets associated with this Basemap instance'
# get current axes instance (if none specified).
if ax is None and self.ax is None:
try:
@@ -1260,7 +1260,7 @@
ax - axes instance (overrides default axes instance)
"""
if self.resolution is None:
- raise AttributeError, 'there are no boundary datasets associated with this Basemap instance'
+ raise AttributeError, 'there are no boundary datasets associated with this Basemap instance'
# get current axes instance (if none specified).
if ax is None and self.ax is None:
try:
@@ -1287,7 +1287,7 @@
ax - axes instance (overrides default axes instance)
"""
if self.resolution is None:
- raise AttributeError, 'there are no boundary datasets associated with this Basemap instance'
+ raise AttributeError, 'there are no boundary datasets associated with this Basemap instance'
# get current axes instance (if none specified).
if ax is None and self.ax is None:
try:
@@ -1516,7 +1516,7 @@
l.set_dashes(dashes)
ax.add_line(l)
# draw labels for parallels
- # parallels not labelled for orthographic, robinson,
+ # parallels not labelled for orthographic, robinson,
# sinusoidal or mollweide.
if self.projection in ['ortho'] and max(labels):
print 'Warning: Cannot label parallels on Orthographic basemap'
@@ -2279,7 +2279,7 @@
# reset current active image (only if pylab is imported).
try:
try: # new contour.
- if CS._A is not None: pylab.gci._current = CS
+ if CS._A is not None: pylab.gci._current = CS
except: # old contour.
if CS[1].mappable is not None: pylab.gci._current = CS[1].mappable
except:
@@ -2340,9 +2340,56 @@
pass
return CS
- def quiver(self, x, y, u, v, scale=None, **kwargs):
+ def quiver(self, x, y, u, v, C=None, **kwargs):
"""
Make a vector plot (u, v) with arrows on the map projection grid (x,y)
+ extra keyword 'ax' can be used to override the default axis instance.
+ Otherwise, the arguments and keyword arguments are the same as for
+ Axes.quiver, except that all of x,y,u,v are required arguments.
+ """
+ if not kwargs.has_key('ax') and self.ax is None:
+ try:
+ ax = pylab.gca()
+ except:
+ import pylab
+ ax = pylab.gca()
+ elif not kwargs.has_key('ax') and self.ax is not None:
+ ax = self.ax
+ else:
+ ax = popd(kwargs,'ax')
+ ny = x.shape[0]; nx = x.shape[1]
+ # allow callers to override the hold state by passing hold=True|False
+ b = ax.ishold()
+ h = popd(kwargs, 'hold', None)
+ if h is not None:
+ ax.hold(h)
+ try:
+ if C is not None:
+ args = (x, y, u, v, c)
+ else:
+ args = (x, y, u, v)
+ ret = ax.quiver(*args, **kwargs)
+ try:
+ pylab.draw_if_interactive()
+ except:
+ pass
+ except:
+ ax.hold(b)
+ raise
+ ax.hold(b)
+ # set axes limits to fit map region.
+ self.set_axes_limits(ax=ax)
+ # make sure axis ticks are turned off.
+ if self.noticks:
+ ax.set_xticks([])
+ ax.set_yticks([])
+ return ret
+
+
+
+ def quiver_classic(self, x, y, u, v, scale=None, **kwargs):
+ """
+ Make a vector plot (u, v) with arrows on the map projection grid (x,y)
If scale is specified, it is used to scale the vectors. If scale=None
(default) arrows are scaled to longest one is equal to the maximum
distance between grid points.
@@ -2372,7 +2419,7 @@
if h is not None:
ax.hold(h)
try:
- ret = ax.quiver(x,y,u,v,scale,**kwargs)
+ ret = ax.quiver_classic(x,y,u,v,scale,**kwargs)
try:
pylab.draw_if_interactive()
except:
@@ -2389,6 +2436,9 @@
ax.set_yticks([])
return ret
+
+
+
def drawlsmask(self,rgba_land,rgba_ocean,lsmask=None,
lsmask_lons=None,lsmask_lats=None,lakes=False,**kwargs):
"""
@@ -2402,14 +2452,14 @@
To make oceans transparent (useful if you just want to mask land
regions over another image), use rgba_ocean = (0,0,255,0).
- If lakes=True, inland lakes are also colored with
+ If lakes=True, inland lakes are also colored with
rgba_ocean (default is lakes=False).
Default land-sea mask is from
http://www.ngdc.noaa.gov/seg/cdroms/graham/graham/graham.htm
and has 5-minute resolution.
- To specify your own land-sea mask, set the
+ To specify your own land-sea mask, set the
lsmask keyword to a (nlats, nlons) array
with 0's for ocean pixels, 1's for land pixels and
optionally 2's for inland lake pixels.
@@ -2596,7 +2646,7 @@
if masked:
xmask = NX.logical_or(NX.less(xcoords,0),NX.greater(xcoords,len(xin)-1))
ymask = NX.logical_or(NX.less(ycoords,0),NX.greater(ycoords,len(yin)-1))
- xymask = NX.logical_or(xmask,ymask)
+ xymask = NX.logical_or(xmask,ymask)
xymask = NX.reshape(xymask,xout.shape)
xcoords = NX.clip(xcoords,0,len(xin)-1)
ycoords = NX.clip(ycoords,0,len(yin)-1)
@@ -2714,7 +2764,7 @@
if masked:
xmask = NX.logical_or(NX.less(xcoords,0),NX.greater(xcoords,len(xin)-1))
ymask = NX.logical_or(NX.less(ycoords,0),NX.greater(ycoords,len(yin)-1))
- xymask = NX.logical_or(xmask,ymask)
+ xymask = NX.logical_or(xmask,ymask)
xcoords = NX.clip(xcoords,0,len(xin)-1)
ycoords = NX.clip(ycoords,0,len(yin)-1)
# interpolate to output grid using bilinear interpolation.
Index: examples/quiver_demo.py
===================================================================
--- examples/quiver_demo.py (revision 2450)
+++ examples/quiver_demo.py (working copy)
@@ -32,8 +32,11 @@
urot,vrot,x,y = m.rotate_vector(u[36:,:],v[36:,:],lons[36:,:],lats[36:,:],returnxy=True)
# plot filled contours over map.
cs = m.contourf(x,y,p[36:,:],15,cmap=cm.jet)
+
# plot wind vectors over map.
-m.quiver(x,y,urot,vrot)
+Q = m.quiver(x,y,urot,vrot) #or specify, e.g., width=0.003, scale=400)
+qk = gca().quiverkey(Q, 0.95, 1.05, 20, '20 m/s', labelpos='E')
+
cax = axes([0.875, 0.1, 0.05, 0.7]) # setup colorbar axes.
colorbar(cax=cax) # draw colorbar
axes(ax) # make the original axes current again
@@ -68,8 +71,11 @@
ax = fig.add_axes([0.1,0.1,0.7,0.7])
# plot image over map
im = m.imshow(pdat,cm.jet)
+
# plot wind vectors over map.
-m.quiver(xv,yv,udat,vdat)
+Q = m.quiver(xv,yv,udat,vdat) # or specify, e.g., width=0.003, scale=400)
+qk = gca().quiverkey(Q, 0.95, 1.05, 20, '20 m/s', labelpos='E')
+
cax = axes([0.875, 0.1, 0.05, 0.7]) # setup colorbar axes.
colorbar(cax=cax) # draw colorbar
axes(ax) # make the original axes current again
@@ -84,5 +90,5 @@
delon = 45.
meridians = arange(-180,180,delon)
m.drawmeridians(meridians,labels=[1,1,1,1])
-title('Surface Winds Winds and Pressure',y=1.075)
+title('Surface Winds Winds and Pressure on proj coordinates',y=1.075)
show()
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel