Attached is a patch that I want to commit to the trunk.
It introduces new attribute "_check_contains" (any name suggestion?)
for Annotation class.
* True : the annotation will only be drawn when self.xy is
inside the axes.
* False : the annotation will always be drawn regardless of
its position.
* None : the self.xy will be checked only if *xycoords* is "data"
The default value is None, i.e., position is only checked if the
xycoords is "data".
I'll commit this soon if others don't object.
Regards,
-JJ
On Fri, May 15, 2009 at 3:44 AM, Ben Coppin <cop...@gmail.com> wrote:
> Thanks! As far as I can tell, this works perfectly.
>
> I agree that this should probably be the default behaviour.
>
> Ben
>
> On Thu, May 14, 2009 at 8:03 PM, Jae-Joon Lee <lee.j.j...@gmail.com> wrote:
>> On Thu, May 14, 2009 at 4:36 AM, Ben Coppin <cop...@gmail.com> wrote:
>>> Hi,
>>>
>>> I've added annotations to a graph I am producing using matplotlib. The
>>> annotations work fine, but when you zoom and pan, the annotations move off
>>> the edge of the chart and are still visible while they're in the main TK
>>> window. Does anyone know of a way to make the annotations disappear when
>>> they move off the edge of the chart?
>>
>> Currently, there is no support for this. However, a monkey patching
>> can be a quick solution for now.
>>
>>
>> from matplotlib.text import Annotation
>>
>> def draw(self, renderer):
>> x, y = self.xy
>> x, y = self._get_xy(x, y, self.xycoords)
>> if not self.axes.bbox.contains(x, y):
>> return
>>
>> self.draw_real(renderer)
>>
>> Annotation.draw_real = Annotation.draw
>> Annotation.draw = draw
>>
>> ann = annotate("test", (0.5, 0.5), xytext=(0.6, 0.6),
>> arrowprops=dict(arrowstyle="->"))
>>
>>
>> I think this should be the default behavior (with optionally turned
>> off). If other developers don't object, i'll try to push this feature
>> into the svn.
>>
>> Regards,
>>
>> -JJ
>>
>>
>>>
>>> Thanks,
>>>
>>> Ben
>>>
>>> ------------------------------------------------------------------------------
>>> The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
>>> production scanning environment may not be a perfect world - but thanks to
>>> Kodak, there's a perfect scanner to get the job done! With the NEW KODAK
>>> i700
>>> Series Scanner you'll get full speed at 300 dpi even with all image
>>> processing features enabled. http://p.sf.net/sfu/kodak-com
>>> _______________________________________________
>>> Matplotlib-users mailing list
>>> Matplotlib-users@lists.sourceforge.net
>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>>
>>>
>>
>
Index: lib/matplotlib/text.py
===================================================================
--- lib/matplotlib/text.py (revision 7100)
+++ lib/matplotlib/text.py (working copy)
@@ -1407,6 +1407,8 @@
else:
self.arrow_patch = None
+ # if True, draw annotation only if self.xy is inside the axes
+ self._check_contains = None
__init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
@@ -1524,15 +1526,39 @@
trans = self.axes.transAxes
return trans.transform_point((x, y))
+ def set_check_contains(self, b):
+ """
+ set *check_contains* attribute.
+ * True : the annotation will only be drawn when self.xy is inside the axes.
+ * False : the annotation will always be drawn regardless of its position.
+ * None : the self.xy will be checked only if *xycoords* is "data"
+ """
+ self._check_contains = b
+
+ def get_check_contains(self):
+ " retrun *check_contains* attribute. "
+ return self._check_contains
+
+
def update_positions(self, renderer):
+ xy_pixel = self._get_position_xy(renderer)
+ self._update_position_xytext(renderer, xy_pixel)
+
+
+ def _get_position_xy(self, renderer):
+ x, y = self.xy
+ return self._get_xy(x, y, self.xycoords)
+
+
+ def _update_position_xytext(self, renderer, xy_pixel):
+
x, y = self.xytext
self._x, self._y = self._get_xy(x, y, self.textcoords)
- x, y = self.xy
- x, y = self._get_xy(x, y, self.xycoords)
+ x, y = xy_pixel
ox0, oy0 = self._x, self._y
ox1, oy1 = x, y
@@ -1608,6 +1634,23 @@
self.arrow.set_clip_box(self.get_clip_box())
+
+ class _SimpleEvent:
+ def __init__(self, xy):
+ self.x, self.y = xy
+
+ def _check_xy(self, renderer, xy_pixel):
+ "given the xy coordinate, check if the annotation need to be drawn"
+
+ b = self.get_check_contains()
+ if b or (b is None and self.xycoords == "data"):
+ # check if self.xy is inside the axes.
+ if not self.axes.contains(Annotation._SimpleEvent(xy_pixel))[0]:
+ return False
+
+ return True
+
+
def draw(self, renderer):
"""
Draw the :class:`Annotation` object to the given *renderer*.
@@ -1617,7 +1660,13 @@
self._renderer = renderer
if not self.get_visible(): return
- self.update_positions(renderer)
+ xy_pixel = self._get_position_xy(renderer)
+
+ if not self._check_xy(renderer, xy_pixel):
+ return
+
+ self._update_position_xytext(renderer, xy_pixel)
+
self.update_bbox_position_size(renderer)
if self.arrow is not None:
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables
unlimited royalty-free distribution of the report engine
for externally facing server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users