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

Reply via email to