@@ -205,13 +205,11 @@ def contains(self, mouseevent):
205
205
# Explicitly use Text.get_window_extent(self) and not
206
206
# self.get_window_extent() so that Annotation.contains does not
207
207
# 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 )
210
211
211
- x , y = mouseevent .x , mouseevent .y
212
- inside = (l <= x <= r and b <= y <= t )
213
212
cattr = {}
214
-
215
213
# if the text has a surrounding patch, also check containment for it,
216
214
# and merge the results with the results for the text.
217
215
if self ._bbox_patch :
@@ -1312,13 +1310,14 @@ def __call__(self, renderer):
1312
1310
"""
1313
1311
if isinstance (self ._artist , Artist ):
1314
1312
bbox = self ._artist .get_window_extent (renderer )
1315
- l , b , w , h = bbox .bounds
1316
1313
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
1318
1316
elif isinstance (self ._artist , BboxBase ):
1319
- l , b , w , h = self ._artist . bounds
1317
+ bbox = self ._artist
1320
1318
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
1322
1321
elif isinstance (self ._artist , Transform ):
1323
1322
x , y = self ._artist .transform (self ._ref_coord )
1324
1323
else :
@@ -1407,7 +1406,7 @@ def _get_xy_transform(self, renderer, s):
1407
1406
# bbox0 = self._get_bbox(renderer, bbox)
1408
1407
1409
1408
if bbox0 is not None :
1410
- xy0 = bbox0 .bounds [: 2 ]
1409
+ xy0 = bbox0 .p0
1411
1410
elif bbox_name == "offset" :
1412
1411
xy0 = self ._get_ref_xy (renderer )
1413
1412
@@ -1426,7 +1425,7 @@ def _get_xy_transform(self, renderer, s):
1426
1425
dpp = fontsize * self .figure .get_dpi () / 72.
1427
1426
tr = Affine2D ().scale (dpp )
1428
1427
elif unit == "fraction" :
1429
- w , h = bbox0 .bounds [ 2 :]
1428
+ w , h = bbox0 .size
1430
1429
tr = Affine2D ().scale (w , h )
1431
1430
else :
1432
1431
raise ValueError ("%s is not a recognized coordinate" % s )
@@ -1823,99 +1822,73 @@ def _update_position_xytext(self, renderer, xy_pixel):
1823
1822
# generate transformation,
1824
1823
self .set_transform (self ._get_xy_transform (renderer , self .anncoords ))
1825
1824
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 )
1896
1883
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 )
1919
1892
1920
1893
@artist .allow_rasterization
1921
1894
def draw (self , renderer ):
0 commit comments