@@ -416,63 +416,42 @@ def calc_label_rot_and_inline(self, slc, ind, lw, lc=None, spacing=5):
416
416
else :
417
417
dp = np .zeros_like (xi )
418
418
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 ))
431
424
432
425
if self .rightside_up :
433
426
# 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
438
428
439
429
# Break contour if desired
440
430
nlc = []
441
431
if len (lc ):
442
432
# Expand range by spacing
443
433
xi = dp + xi + np .array ([- spacing , spacing ])
444
434
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 ]
464
443
465
444
# Actually break contours
466
445
if closed :
467
446
# 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 ]) )
470
449
else :
471
450
# 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 ]:]]) )
476
455
477
456
# The current implementation removes contours completely
478
457
# covered by labels. Uncomment line below to keep
0 commit comments