@@ -253,8 +253,12 @@ def _init(self):
253253 self ._set_transform ()
254254 _pivot = self .Q .pivot
255255 self .Q .pivot = self .pivot [self .labelpos ]
256+ # Hack: save and restore the Umask
257+ _mask = self .Q .Umask
258+ self .Q .Umask = ma .nomask
256259 self .verts = self .Q ._make_verts (np .array ([self .U ]),
257260 np .zeros ((1 ,)))
261+ self .Q .Umask = _mask
258262 self .Q .pivot = _pivot
259263 kw = self .Q .polykw
260264 kw .update (self .kw )
@@ -388,9 +392,9 @@ def _parse_args(self, *args):
388392 X , Y , U , V , C = [None ]* 5
389393 args = list (args )
390394 if len (args ) == 3 or len (args ) == 5 :
391- C = ma . masked_invalid (args .pop (- 1 ), copy = False )
392- V = ma . masked_invalid (args .pop (- 1 ), copy = False )
393- U = ma . masked_invalid (args .pop (- 1 ), copy = False )
395+ C = np . asanyarray (args .pop (- 1 ))
396+ V = np . asanyarray (args .pop (- 1 ))
397+ U = np . asanyarray (args .pop (- 1 ))
394398 if U .ndim == 1 :
395399 nr , nc = 1 , U .shape [0 ]
396400 else :
@@ -430,10 +434,21 @@ def draw(self, renderer):
430434 collections .PolyCollection .draw (self , renderer )
431435
432436 def set_UVC (self , U , V , C = None ):
433- self .U = U .ravel ()
434- self .V = V .ravel ()
437+ U = ma .masked_invalid (U , copy = False ).ravel ()
438+ V = ma .masked_invalid (V , copy = False ).ravel ()
439+ mask = ma .mask_or (U .mask , V .mask , copy = False , shrink = True )
440+ if C is not None :
441+ C = ma .masked_invalid (C , copy = False ).ravel ()
442+ mask = ma .mask_or (mask , C .mask , copy = False , shrink = True )
443+ if mask is ma .nomask :
444+ C = C .filled ()
445+ else :
446+ C = ma .array (C , mask = mask , copy = False )
447+ self .U = U .filled (1 )
448+ self .V = V .filled (1 )
449+ self .Umask = mask
435450 if C is not None :
436- self .set_array (C . ravel () )
451+ self .set_array (C )
437452 self ._new_UV = True
438453
439454 def _set_transform (self ):
@@ -463,32 +478,33 @@ def _set_transform(self):
463478
464479 def _angles (self , U , V , eps = 0.001 ):
465480 xy = self .ax .transData .transform (self .XY )
466- uv = ma .hstack ((U [:,np .newaxis ], V [:,np .newaxis ])). filled ( 0 )
481+ uv = np .hstack ((U [:,np .newaxis ], V [:,np .newaxis ]))
467482 xyp = self .ax .transData .transform (self .XY + eps * uv )
468483 dxy = xyp - xy
469- ang = ma .arctan2 (dxy [:,1 ], dxy [:,0 ])
484+ ang = np .arctan2 (dxy [:,1 ], dxy [:,0 ])
470485 return ang
471486
472487 def _make_verts (self , U , V ):
473- uv = ma . asarray (U + V * 1j )
474- a = ma .absolute (uv )
488+ uv = (U + V * 1j )
489+ a = np .absolute (uv )
475490 if self .scale is None :
476491 sn = max (10 , math .sqrt (self .N ))
477- scale = 1.8 * a .mean () * sn / self .span # crude auto-scaling
492+ scale = 1.8 * a [ ~ self . Umask ] .mean () * sn / self .span # crude auto-scaling
478493 self .scale = scale
479494 length = a / (self .scale * self .width )
480495 X , Y = self ._h_arrows (length )
481496 if self .angles == 'xy' :
482- theta = self ._angles (U , V ). filled ( 0 )
497+ theta = self ._angles (U , V )
483498 elif self .angles == 'uv' :
484- theta = np .angle (uv . filled ( 0 ) )
499+ theta = np .angle (uv )
485500 else :
486501 theta = ma .masked_invalid (self .angles , copy = False ).filled (0 )
487502 theta *= (np .pi / 180.0 )
488503 theta .shape = (theta .shape [0 ], 1 ) # for broadcasting
489504 xy = (X + Y * 1j ) * np .exp (1j * theta )* self .width
490505 xy = xy [:,:,np .newaxis ]
491- XY = ma .concatenate ((xy .real , xy .imag ), axis = 2 )
506+ XY = np .concatenate ((xy .real , xy .imag ), axis = 2 )
507+
492508 return XY
493509
494510
@@ -502,8 +518,8 @@ def _h_arrows(self, length):
502518 length = length .reshape (N , 1 )
503519 # This number is chosen based on when pixel values overflow in Agg
504520 # causing rendering errors
505- length = np .minimum (length , 2 ** 16 )
506-
521+ # length = np.minimum(length, 2 ** 16)
522+ np . clip ( length , 0 , 2 ** 16 , out = length )
507523 # x, y: normal horizontal arrow
508524 x = np .array ([0 , - self .headaxislength ,
509525 - self .headlength , 0 ], np .float64 )
@@ -514,21 +530,20 @@ def _h_arrows(self, length):
514530 x0 = np .array ([0 , minsh - self .headaxislength ,
515531 minsh - self .headlength , minsh ], np .float64 )
516532 y0 = 0.5 * np .array ([1 , 1 , self .headwidth , 0 ], np .float64 )
517- ii = [0 ,1 ,2 ,3 ,2 ,1 ,0 ]
533+ ii = [0 ,1 ,2 ,3 ,2 ,1 ,0 , 0 ]
518534 X = x .take (ii , 1 )
519535 Y = y .take (ii , 1 )
520- Y [:, 3 :] *= - 1
536+ Y [:, 3 :- 1 ] *= - 1
521537 X0 = x0 .take (ii )
522538 Y0 = y0 .take (ii )
523- Y0 [3 :] *= - 1
539+ Y0 [3 :- 1 ] *= - 1
524540 shrink = length / minsh
525541 X0 = shrink * X0 [np .newaxis ,:]
526542 Y0 = shrink * Y0 [np .newaxis ,:]
527- short = np .repeat (length < minsh , 7 , axis = 1 )
528- #print 'short', length < minsh
543+ short = np .repeat (length < minsh , 8 , axis = 1 )
529544 # Now select X0, Y0 if short, otherwise X, Y
530- X = ma . where ( short , X0 , X )
531- Y = ma . where ( short , Y0 , Y )
545+ np . putmask ( X , short , X0 )
546+ np . putmask ( Y , short , Y0 )
532547 if self .pivot [:3 ] == 'mid' :
533548 X -= 0.5 * X [:,3 , np .newaxis ]
534549 elif self .pivot [:3 ] == 'tip' :
@@ -538,14 +553,18 @@ def _h_arrows(self, length):
538553 tooshort = length < self .minlength
539554 if tooshort .any ():
540555 # Use a heptagonal dot:
541- th = np .arange (0 ,7 ,1 , np .float64 ) * (np .pi / 3.0 )
556+ th = np .arange (0 ,8 ,1 , np .float64 ) * (np .pi / 3.0 )
542557 x1 = np .cos (th ) * self .minlength * 0.5
543558 y1 = np .sin (th ) * self .minlength * 0.5
544559 X1 = np .repeat (x1 [np .newaxis , :], N , axis = 0 )
545560 Y1 = np .repeat (y1 [np .newaxis , :], N , axis = 0 )
546- tooshort = ma .repeat (tooshort , 7 , 1 )
547- X = ma .where (tooshort , X1 , X )
548- Y = ma .where (tooshort , Y1 , Y )
561+ tooshort = np .repeat (tooshort , 8 , 1 )
562+ np .putmask (X , tooshort , X1 )
563+ np .putmask (Y , tooshort , Y1 )
564+ if self .Umask is not ma .nomask :
565+ mask = np .repeat (self .Umask [:,np .newaxis ], 8 , 1 )
566+ X = ma .array (X , mask = mask , copy = False )
567+ Y = ma .array (Y , mask = mask , copy = False )
549568 return X , Y
550569
551570 quiver_doc = _quiver_doc
0 commit comments