@@ -110,6 +110,9 @@ def clabel(self, *args, **kwargs):
110110 placement, delete or backspace act like the third mouse button,
111111 and any other key will select a label location).
112112
113+ *manual* can be an iterable object of x,y tuples. Contour labels
114+ will be created as if mouse is clicked at each x,y positions.
115+
113116 *rightside_up*:
114117 if *True* (default), label rotations will always be plus
115118 or minus 90 degrees from level.
@@ -197,7 +200,12 @@ def clabel(self, *args, **kwargs):
197200 #self.labelCValues = [] # same
198201 self .labelXYs = []
199202
200- if self .labelManual :
203+ if cbook .iterable (self .labelManual ):
204+ for x ,y in self .labelManual :
205+ self .add_label_near (x , y , inline ,
206+ inline_spacing )
207+
208+ elif self .labelManual :
201209 print ('Select label locations manually using first mouse button.' )
202210 print ('End manual selection with second mouse button.' )
203211 if not inline :
@@ -532,6 +540,72 @@ def add_label_clabeltext(self,x,y,rotation,lev,cvalue):
532540 self ._add_label (t , x , y , lev , cvalue )
533541
534542
543+ def add_label_near (self , x , y , inline = True , inline_spacing = 5 ,
544+ transform = None ):
545+ """
546+ Add a label near the point (x, y) of the given transform.
547+ If transform is None, data transform is used. If transform is
548+ False, IdentityTransform is used.
549+
550+ *inline*:
551+ controls whether the underlying contour is removed or
552+ not. Default is *True*.
553+
554+ *inline_spacing*:
555+ space in pixels to leave on each side of label when
556+ placing inline. Defaults to 5. This spacing will be
557+ exact for labels at locations where the contour is
558+ straight, less so for labels on curved contours.
559+ """
560+
561+ if transform is None :
562+ transform = self .ax .transData
563+
564+ if transform :
565+ x ,y = transform .transform_point ((x , y ))
566+
567+ conmin ,segmin ,imin ,xmin ,ymin = self .find_nearest_contour (
568+ x , y , self .labelIndiceList )[:5 ]
569+
570+ # Get index of nearest level in subset of levels used for labeling
571+ lmin = self .labelIndiceList .index (conmin )
572+
573+ # Coordinates of contour
574+ paths = self .collections [conmin ].get_paths ()
575+ lc = paths [segmin ].vertices
576+
577+ # In pixel/screen space
578+ slc = self .ax .transData .transform (lc )
579+
580+ # Get label width for rotating labels and breaking contours
581+ lw = self .get_label_width (self .labelLevelList [lmin ],
582+ self .labelFmt , self .labelFontSizeList [lmin ])
583+
584+ """
585+ # requires python 2.5
586+ # Figure out label rotation.
587+ rotation,nlc = cs.calc_label_rot_and_inline(
588+ slc, imin, lw, lc if self.inline else [],
589+ self.inline_spacing )
590+ """
591+ # Figure out label rotation.
592+ if inline : lcarg = lc
593+ else : lcarg = None
594+ rotation ,nlc = self .calc_label_rot_and_inline (
595+ slc , imin , lw , lcarg ,
596+ inline_spacing )
597+
598+ self .add_label (xmin ,ymin ,rotation ,self .labelLevelList [lmin ],
599+ self .labelCValueList [lmin ])
600+
601+ if inline :
602+ # Remove old, not looping over paths so we can do this up front
603+ paths .pop (segmin )
604+
605+ # Add paths if not empty or single point
606+ for n in nlc :
607+ if len (n )> 1 :
608+ paths .append ( mpath .Path (n ) )
535609
536610 def pop_label (self ,index = - 1 ):
537611 '''Defaults to removing last label, but any index can be supplied'''
0 commit comments