@@ -124,6 +124,7 @@ class Text(Artist):
124124 """Handle storing and drawing of text in window or data coordinates."""
125125
126126 zorder = 3
127+ _charsize_cache = dict ()
127128
128129 def __repr__ (self ):
129130 return "Text(%s, %s, %s)" % (self ._x , self ._y , repr (self ._text ))
@@ -279,6 +280,38 @@ def _get_multialignment(self):
279280 else :
280281 return self ._horizontalalignment
281282
283+ def _char_index_at (self , x ):
284+ """
285+ Calculate the index closest to the coordinate x in display space.
286+
287+ The position of text[index] is assumed to be the sum of the widths
288+ of all preceding characters text[:index].
289+
290+ This works only on single line texts.
291+ """
292+ if not self ._text :
293+ return 0
294+
295+ text = self ._text
296+
297+ fontproperties = str (self ._fontproperties )
298+ if fontproperties not in Text ._charsize_cache :
299+ Text ._charsize_cache [fontproperties ] = dict ()
300+
301+ charsize_cache = Text ._charsize_cache [fontproperties ]
302+ for char in set (text ):
303+ if char not in charsize_cache :
304+ self .set_text (char )
305+ bb = self .get_window_extent ()
306+ charsize_cache [char ] = bb .x1 - bb .x0
307+
308+ self .set_text (text )
309+ bb = self .get_window_extent ()
310+
311+ size_accum = np .cumsum ([0 ] + [charsize_cache [x ] for x in text ])
312+ std_x = x - bb .x0
313+ return (np .abs (size_accum - std_x )).argmin ()
314+
282315 def get_rotation (self ):
283316 """Return the text angle in degrees between 0 and 360."""
284317 if self .get_transform_rotates_text ():
0 commit comments