@@ -416,63 +416,42 @@ def calc_label_rot_and_inline(self, slc, ind, lw, lc=None, spacing=5):
416416 else :
417417 dp = np .zeros_like (xi )
418418
419- ll = mlab .less_simple_linear_interpolation (pl , slc , dp + xi ,
420- extrap = True )
421-
422- # get vector in pixel space coordinates from one point to other
423- dd = np .diff (ll , axis = 0 ).ravel ()
424-
425- # Get angle of vector - must be calculated in pixel space for
426- # text rotation to work correctly
427- if np .all (dd == 0 ): # Must deal with case of zero length label
428- rotation = 0.0
429- else :
430- rotation = np .rad2deg (np .arctan2 (dd [1 ], dd [0 ]))
419+ # Get angle of vector between the two ends of the label - must be
420+ # calculated in pixel space for text rotation to work correctly.
421+ (dx ,), (dy ,) = (np .diff (np .interp (dp + xi , pl , slc_col ))
422+ for slc_col in slc .T )
423+ rotation = np .rad2deg (np .arctan2 (dy , dx ))
431424
432425 if self .rightside_up :
433426 # Fix angle so text is never upside-down
434- if rotation > 90 :
435- rotation = rotation - 180.0
436- if rotation < - 90 :
437- rotation = 180.0 + rotation
427+ rotation = (rotation + 90 ) % 180 - 90
438428
439429 # Break contour if desired
440430 nlc = []
441431 if len (lc ):
442432 # Expand range by spacing
443433 xi = dp + xi + np .array ([- spacing , spacing ])
444434
445- # Get indices near points of interest
446- I = mlab .less_simple_linear_interpolation (
447- pl , np .arange (len (pl )), xi , extrap = False )
448-
449- # If those indices aren't beyond contour edge, find x,y
450- if (not np .isnan (I [0 ])) and int (I [0 ]) != I [0 ]:
451- xy1 = mlab .less_simple_linear_interpolation (
452- pl , lc , [xi [0 ]])
453-
454- if (not np .isnan (I [1 ])) and int (I [1 ]) != I [1 ]:
455- xy2 = mlab .less_simple_linear_interpolation (
456- pl , lc , [xi [1 ]])
457-
458- # Round to integer values but keep as float
459- # To allow check against nan below
460- # Ignore nans here to avoid throwing an error on Appveyor build
461- # (can possibly be removed when build uses numpy 1.13)
462- with np .errstate (invalid = 'ignore' ):
463- I = [np .floor (I [0 ]), np .ceil (I [1 ])]
435+ # Get (integer) indices near points of interest; use -1 as marker
436+ # for out of bounds.
437+ I = np .interp (xi , pl , np .arange (len (pl )), left = - 1 , right = - 1 )
438+ I = [np .floor (I [0 ]).astype (int ), np .ceil (I [1 ]).astype (int )]
439+ if I [0 ] != - 1 :
440+ xy1 = [np .interp (xi [0 ], pl , lc_col ) for lc_col in lc .T ]
441+ if I [1 ] != - 1 :
442+ xy2 = [np .interp (xi [1 ], pl , lc_col ) for lc_col in lc .T ]
464443
465444 # Actually break contours
466445 if closed :
467446 # This will remove contour if shorter than label
468- if np .all (~ np . isnan ( I ) ):
469- nlc .append (np .r_ [xy2 , lc [int ( I [1 ]): int ( I [0 ]) + 1 ], xy1 ])
447+ if np .all (I != - 1 ):
448+ nlc .append (np .row_stack ( [xy2 , lc [I [1 ]: I [0 ]+ 1 ], xy1 ]) )
470449 else :
471450 # These will remove pieces of contour if they have length zero
472- if not np . isnan ( I [0 ]) :
473- nlc .append (np .r_ [lc [:int ( I [0 ]) + 1 ], xy1 ])
474- if not np . isnan ( I [1 ]) :
475- nlc .append (np .r_ [xy2 , lc [int ( I [1 ]) :]])
451+ if I [0 ] != - 1 :
452+ nlc .append (np .row_stack ( [lc [:I [0 ]+ 1 ], xy1 ]) )
453+ if I [1 ] != - 1 :
454+ nlc .append (np .row_stack ( [xy2 , lc [I [1 ]:]]) )
476455
477456 # The current implementation removes contours completely
478457 # covered by labels. Uncomment line below to keep
0 commit comments