@@ -205,13 +205,11 @@ def contains(self, mouseevent):
205205 # Explicitly use Text.get_window_extent(self) and not
206206 # self.get_window_extent() so that Annotation.contains does not
207207 # accidentally cover the entire annotation bounding box.
208- l , b , w , h = Text .get_window_extent (self ).bounds
209- r , t = l + w , b + h
208+ bbox = Text .get_window_extent (self )
209+ inside = (bbox .x0 <= mouseevent .x <= bbox .x1
210+ and bbox .y0 <= mouseevent .y <= bbox .y1 )
210211
211- x , y = mouseevent .x , mouseevent .y
212- inside = (l <= x <= r and b <= y <= t )
213212 cattr = {}
214-
215213 # if the text has a surrounding patch, also check containment for it,
216214 # and merge the results with the results for the text.
217215 if self ._bbox_patch :
@@ -1312,13 +1310,14 @@ def __call__(self, renderer):
13121310 """
13131311 if isinstance (self ._artist , Artist ):
13141312 bbox = self ._artist .get_window_extent (renderer )
1315- l , b , w , h = bbox .bounds
13161313 xf , yf = self ._ref_coord
1317- x , y = l + w * xf , b + h * yf
1314+ x = bbox .x0 + bbox .width * xf
1315+ y = bbox .y0 + bbox .height * yf
13181316 elif isinstance (self ._artist , BboxBase ):
1319- l , b , w , h = self ._artist . bounds
1317+ bbox = self ._artist
13201318 xf , yf = self ._ref_coord
1321- x , y = l + w * xf , b + h * yf
1319+ x = bbox .x0 + bbox .width * xf
1320+ y = bbox .y0 + bbox .height * yf
13221321 elif isinstance (self ._artist , Transform ):
13231322 x , y = self ._artist .transform (self ._ref_coord )
13241323 else :
@@ -1407,7 +1406,7 @@ def _get_xy_transform(self, renderer, s):
14071406 # bbox0 = self._get_bbox(renderer, bbox)
14081407
14091408 if bbox0 is not None :
1410- xy0 = bbox0 .bounds [: 2 ]
1409+ xy0 = bbox0 .p0
14111410 elif bbox_name == "offset" :
14121411 xy0 = self ._get_ref_xy (renderer )
14131412
@@ -1426,7 +1425,7 @@ def _get_xy_transform(self, renderer, s):
14261425 dpp = fontsize * self .figure .get_dpi () / 72.
14271426 tr = Affine2D ().scale (dpp )
14281427 elif unit == "fraction" :
1429- w , h = bbox0 .bounds [ 2 :]
1428+ w , h = bbox0 .size
14301429 tr = Affine2D ().scale (w , h )
14311430 else :
14321431 raise ValueError ("%s is not a recognized coordinate" % s )
@@ -1823,99 +1822,73 @@ def _update_position_xytext(self, renderer, xy_pixel):
18231822 # generate transformation,
18241823 self .set_transform (self ._get_xy_transform (renderer , self .anncoords ))
18251824
1826- ox0 , oy0 = self ._get_xy_display ()
1827- ox1 , oy1 = xy_pixel
1828-
1829- if self .arrowprops is not None :
1830- x0 , y0 = xy_pixel
1831- l , b , w , h = Text .get_window_extent (self , renderer ).bounds
1832- r = l + w
1833- t = b + h
1834- xc = 0.5 * (l + r )
1835- yc = 0.5 * (b + t )
1836-
1837- d = self .arrowprops .copy ()
1838- ms = d .pop ("mutation_scale" , self .get_size ())
1839- self .arrow_patch .set_mutation_scale (ms )
1840-
1841- if "arrowstyle" not in d :
1842- # Approximately simulate the YAArrow.
1843- # Pop its kwargs:
1844- shrink = d .pop ('shrink' , 0.0 )
1845- width = d .pop ('width' , 4 )
1846- headwidth = d .pop ('headwidth' , 12 )
1847- # Ignore frac--it is useless.
1848- frac = d .pop ('frac' , None )
1849- if frac is not None :
1850- cbook ._warn_external (
1851- "'frac' option in 'arrowprops' is no longer supported;"
1852- " use 'headlength' to set the head length in points." )
1853- headlength = d .pop ('headlength' , 12 )
1854-
1855- # NB: ms is in pts
1856- stylekw = dict (head_length = headlength / ms ,
1857- head_width = headwidth / ms ,
1858- tail_width = width / ms )
1859-
1860- self .arrow_patch .set_arrowstyle ('simple' , ** stylekw )
1861-
1862- # using YAArrow style:
1863- # pick the (x, y) corner of the text bbox closest to point
1864- # annotated
1865- xpos = ((l , 0 ), (xc , 0.5 ), (r , 1 ))
1866- ypos = ((b , 0 ), (yc , 0.5 ), (t , 1 ))
1867-
1868- _ , (x , relposx ) = min ((abs (val [0 ] - x0 ), val ) for val in xpos )
1869- _ , (y , relposy ) = min ((abs (val [0 ] - y0 ), val ) for val in ypos )
1870-
1871- self ._arrow_relpos = (relposx , relposy )
1872-
1873- r = np .hypot ((y - y0 ), (x - x0 ))
1874- shrink_pts = shrink * r / renderer .points_to_pixels (1 )
1875- self .arrow_patch .shrinkA = shrink_pts
1876- self .arrow_patch .shrinkB = shrink_pts
1877-
1878- # adjust the starting point of the arrow relative to
1879- # the textbox.
1880- # TODO : Rotation needs to be accounted.
1881- relpos = self ._arrow_relpos
1882- bbox = Text .get_window_extent (self , renderer )
1883- ox0 = bbox .x0 + bbox .width * relpos [0 ]
1884- oy0 = bbox .y0 + bbox .height * relpos [1 ]
1885-
1886- # The arrow will be drawn from (ox0, oy0) to (ox1,
1887- # oy1). It will be first clipped by patchA and patchB.
1888- # Then it will be shrunk by shrinkA and shrinkB
1889- # (in points). If patch A is not set, self.bbox_patch
1890- # is used.
1891-
1892- self .arrow_patch .set_positions ((ox0 , oy0 ), (ox1 , oy1 ))
1893-
1894- if "patchA" in d :
1895- self .arrow_patch .set_patchA (d .pop ("patchA" ))
1825+ if self .arrowprops is None :
1826+ return
1827+
1828+ x1 , y1 = xy_pixel # Annotated position.
1829+ bbox = Text .get_window_extent (self , renderer )
1830+
1831+ d = self .arrowprops .copy ()
1832+ ms = d .pop ("mutation_scale" , self .get_size ())
1833+ self .arrow_patch .set_mutation_scale (ms )
1834+
1835+ if "arrowstyle" not in d :
1836+ # Approximately simulate the YAArrow.
1837+ # Pop its kwargs:
1838+ shrink = d .pop ('shrink' , 0.0 )
1839+ width = d .pop ('width' , 4 )
1840+ headwidth = d .pop ('headwidth' , 12 )
1841+ # Ignore frac--it is useless.
1842+ frac = d .pop ('frac' , None )
1843+ if frac is not None :
1844+ cbook ._warn_external (
1845+ "'frac' option in 'arrowprops' is no longer supported;"
1846+ " use 'headlength' to set the head length in points." )
1847+ headlength = d .pop ('headlength' , 12 )
1848+
1849+ # NB: ms is in pts
1850+ stylekw = dict (head_length = headlength / ms ,
1851+ head_width = headwidth / ms ,
1852+ tail_width = width / ms )
1853+
1854+ self .arrow_patch .set_arrowstyle ('simple' , ** stylekw )
1855+
1856+ # using YAArrow style:
1857+ # pick the corner of the text bbox closest to annotated point.
1858+ xpos = [(bbox .x0 , 0 ), ((bbox .x0 + bbox .x1 ) / 2 , 0.5 ), (bbox .x1 , 1 )]
1859+ ypos = [(bbox .y0 , 0 ), ((bbox .y0 + bbox .y1 ) / 2 , 0.5 ), (bbox .y1 , 1 )]
1860+ x , relposx = min (xpos , key = lambda v : abs (v [0 ] - x1 ))
1861+ y , relposy = min (ypos , key = lambda v : abs (v [0 ] - y1 ))
1862+ self ._arrow_relpos = (relposx , relposy )
1863+ r = np .hypot (y - y1 , x - x1 )
1864+ shrink_pts = shrink * r / renderer .points_to_pixels (1 )
1865+ self .arrow_patch .shrinkA = self .arrow_patch .shrinkB = shrink_pts
1866+
1867+ # adjust the starting point of the arrow relative to the textbox.
1868+ # TODO : Rotation needs to be accounted.
1869+ relposx , relposy = self ._arrow_relpos
1870+ x0 = bbox .x0 + bbox .width * relposx
1871+ y0 = bbox .y0 + bbox .height * relposy
1872+
1873+ # The arrow will be drawn from (x0, y0) to (x1, y1). It will be first
1874+ # clipped by patchA and patchB. Then it will be shrunk by shrinkA and
1875+ # shrinkB (in points). If patch A is not set, self.bbox_patch is used.
1876+ self .arrow_patch .set_positions ((x0 , y0 ), (x1 , y1 ))
1877+
1878+ if "patchA" in d :
1879+ self .arrow_patch .set_patchA (d .pop ("patchA" ))
1880+ else :
1881+ if self ._bbox_patch :
1882+ self .arrow_patch .set_patchA (self ._bbox_patch )
18961883 else :
1897- if self ._bbox_patch :
1898- self .arrow_patch .set_patchA (self ._bbox_patch )
1899- else :
1900- pad = renderer .points_to_pixels (4 )
1901- if self .get_text () == "" :
1902- self .arrow_patch .set_patchA (None )
1903- return
1904-
1905- bbox = Text .get_window_extent (self , renderer )
1906- l , b , w , h = bbox .bounds
1907- l -= pad / 2.
1908- b -= pad / 2.
1909- w += pad
1910- h += pad
1911- r = Rectangle (xy = (l , b ),
1912- width = w ,
1913- height = h ,
1914- )
1915- r .set_transform (IdentityTransform ())
1916- r .set_clip_on (False )
1917-
1918- self .arrow_patch .set_patchA (r )
1884+ if self .get_text () == "" :
1885+ self .arrow_patch .set_patchA (None )
1886+ return
1887+ pad = renderer .points_to_pixels (4 )
1888+ r = Rectangle (xy = (bbox .x0 - pad / 2 , bbox .y0 - pad / 2 ),
1889+ width = bbox .width + pad , height = bbox .height + pad ,
1890+ transform = IdentityTransform (), clip_on = False )
1891+ self .arrow_patch .set_patchA (r )
19191892
19201893 @artist .allow_rasterization
19211894 def draw (self , renderer ):
0 commit comments