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