Re: [Matplotlib-users] Cocoa Backend on Snow Leopard
On Tue, Sep 22, 2009 at 2:53 PM, Pierre GM pgmdevl...@gmail.com wrote: On Sep 19, 2009, at 12:55 PM, Pierre GM wrote: All, I'm trying to use the Cocoa backend on Snow Leopard, using r7791 (GCC 4.2.1 / Python 2.6.1 from Apple, 64b) Unfortunately, a simple `plot(range(10),range(10))` gives me an empty window and error message as such: Python[53010:d07] Inconsistent set of values to create NSBitmapImageRep /Users/pierregm/.local/lib/python2.6/site-packages/matplotlib/ backends/backend_cocoaagg.py:140: UninitializedDeallocWarning: leaking an uninitialized object of type NSBitmapImageRep 32) # bits per pixel Can anybody reproduce it ? Would anybody have some ideas on how to fix that ? Thx a lot in advance. P. FYI, the build log can be accessed at: http://pastebin.com/d5b3c1838 I'm very, very sorry to bump my own thread, but I'm in a bit of a pickle. Matplotlib installs and runs nicely on my Snow Leopard installation, but I'm blind: cocoa fails, wxpython is 32b only and compiling Qt4 is becoming increasingly frustrating on a 64b machine. Any help or hint would be really, really appreciated. (and once again, sorry for my being rude) P. I'm not sure if you have the option to go 32-bit, but the cocoa backend works fine on snow leopard with a 32-bit build (-arch i386), that I built on leopard prior to upgrading. The 64 bit transition should be interesting, especially given the persistence of heritage universal (PPC) build processes. -Eric -- Come build with us! The BlackBerryreg; Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9#45;12, 2009. Register now#33; http://p.sf.net/sfu/devconf ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Re: [Matplotlib-users] Updated Lasso Demo
+1 for including Brian's changes in the shipping example. Brian, You might also be interested in an alternate, polygon-based lasso I developed a while back. Though it meets my needs, beware of backend-specific problems with idle events that I never resolved. -Eric http://www.nabble.com/Alternate-lasso:-click-to-form-polygon-td18724261.html On Sun, Dec 7, 2008 at 10:24 AM, B Clowers clowe...@yahoo.com wrote: When running the initial lasso demo I found that only one lasso event was allowed and other canvas interaction events (e.g. zooming) would not work properly after the lasso event. As such I came up with my own solution to the problem by modifying the example source. The primary addition was a button release event call and a boolean to keep track whether the lasso was the last event to lock the widget from interaction. Anyway, I hope it can help someone else out. Cheers, Brian Show how to use a lasso to select a set of points and get the indices of the selected points. A callback is used to change the color of the selected points This is currently a proof-of-concept implementation (though it is usable as is). There will be some refinement of the API and the inside polygon detection routine. from matplotlib.widgets import Lasso import matplotlib.mlab from matplotlib.nxutils import points_inside_poly from matplotlib.colors import colorConverter from matplotlib.collections import RegularPolyCollection from matplotlib.pyplot import figure, show from numpy import nonzero from numpy.random import rand class Datum: colorin = colorConverter.to_rgba('red') colorout = colorConverter.to_rgba('green') def __init__(self, x, y, include=False): self.x = x self.y = y if include: self.color = self.colorin else: self.color = self.colorout class LassoManager: def __init__(self, ax, data): self.axes = ax self.canvas = ax.figure.canvas self.data = data #the lasso lock boolean is used to tell whether another #widget event has priority self.lassoLock = False self.Nxy = len(data) facecolors = [d.color for d in data] self.xys = [(d.x, d.y) for d in data] fig = ax.figure self.collection = RegularPolyCollection( fig.dpi, 6, sizes=(100,), facecolors=facecolors, offsets = self.xys, transOffset = ax.transData) ax.add_collection(self.collection) self.cid = self.canvas.mpl_connect('button_press_event', self.onpress) self.cidRelease = self.canvas.mpl_connect('button_release_event', self.onrelease) self.ind = None def callback(self, verts): facecolors = self.collection.get_facecolors() ind = nonzero(points_inside_poly(self.xys, verts))[0] for i in range(self.Nxy): if i in ind: facecolors[i] = Datum.colorin else: facecolors[i] = Datum.colorout self.canvas.draw_idle() self.canvas.widgetlock.release(self.lasso) #del self.lasso self.ind = ind def onpress(self, event): if self.canvas.widgetlock.locked(): return if event.inaxes is None: return self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback) # acquire a lock on the widget drawing self.canvas.widgetlock(self.lasso) # establish boolean that can be used to release the widgetlock self.lassoLock = True def onrelease(self, event): 'on release we reset the press data' # test whether the widgetlock was initiated by the lasso if self.lassoLock: self.canvas.widgetlock.release(self.lasso) self.lassoLock = False print self.ind if __name__ == '__main__': data = [Datum(*xy) for xy in rand(100, 2)] fig = figure() ax = fig.add_subplot(111, xlim=(0,1), ylim=(0,1), autoscale_on=False) lman = LassoManager(ax, data) show() -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at
Re: [Matplotlib-users] Animate scatter plots
Strange, strange. iPython is apparently having some effect here: I tried ipython -pylab animation.py and I got a figure with the initial plot, but nothing further happened. After closing the plot, I typed run animation.py at the ipython prompt, and saw the initial plot, erasure, and animation that I expected. Can you try running with a plain python animation.py I've attached a new version of the script with some changes suggested offline by Ryan May - he was seeing platform or wx-specific behavior related to event handling. All bugs remaining are mine :) -Eric On Sun, Nov 23, 2008 at 6:20 PM, Cohen-Tanugi Johann [EMAIL PROTECTED] wrote: hi, I tried your script, commenting/uncommenting the backend line, but I still get: [EMAIL PROTECTED] ~]$ ipython -pylab MACROS/animation.py --- AttributeErrorTraceback (most recent call last) /home/cohen/MACROS/animation.py in module() 274 p.show() 275 -- 276 t = test() 277 278 /home/cohen/MACROS/animation.py in __init__(self) 270 271 # cid = p.gcf().canvas.mpl_connect('idle_event', self.update) -- 272 wx.GetApp().Bind(wx.EVT_IDLE, self.update) 273 274 p.show() AttributeError: 'NoneType' object has no attribute 'Bind' WARNING: Failure executing file: MACROS/animation.py I am using MPL revision 6440. cheers, Johann Eric Bruning wrote: Hi Eric, On Fri, Nov 21, 2008 at 11:19 AM, Eric Jonas [EMAIL PROTECTED] wrote: I've looked through the latest examples as well as google and the list archives, and am still at a loss -- can anyone point me to an example of how to animate a scatter plot? I've attached a somewhat unpolished but functional example that shows time-synchronized animation of multiple scatter plots. It uses the wx backend explicitly, due to some issues with the idle event handling. The collection returned by scatter() lacks anything akin to a set_data method. Yup, you want this instead: collection.set_offsets(xy) collection.set_array(s) -Eric - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users import matplotlib # matplotlib.use('WxAgg') import time import wx import sys import numpy as np class AnimationController(object): def __init__(self, duration, animations, leader=None): Single controller of animations. Manages binding to wx. Binding to wx in each individual animator blocks drawing of all but the last animator. duration: Total time to taken to draw the animation. Approximate, but won't be exceeded by more than one frame redraw interval. animations: sequence of Animate objects that are to be animated simultaneously. self.animations = animations self.duration = duration if leader == None: self.leader = animations[0] else: self.leader = leader # When animating by points, only the lead artist should animate by points, # and the others should animate by data intervals up to the appropriate time. if self.leader.framing == 'point_intervals': for animation in self.animations: if animation != self.leader: animation.framing = 'data_intervals' self.tstart = time.time() wx.GetApp().Bind(wx.EVT_IDLE, self.control_update) # use a timer to generate new idle_events, so that the frame rate is limited. # calling WakeUpIdle at the end of self.idle_kick = wx.Timer() wx.GetApp().Bind(wx.EVT_TIMER, lambda e: wx.WakeUpIdle(), self.idle_kick) self.idle_kick.Start(40, oneShot=False) # self.cid = self.animations[0].artist.axes.figure.canvas.mpl_connect('idle_event', self.control_update) def control_update(self, *args): time_fraction = (time.time() - self.tstart) / self.duration # only restore the background for the first frame drawn. # otherwise, only the last animation will appear to animate restore = True # handle
Re: [Matplotlib-users] plotting labels for each 'artist' in a basemap
Can you post a complete, free-standing example script which replicates the problem import matplotlib.pyplot as plt f=plt.figure() ax=f.add_subplot(111) ax.plot(range(10)) ax.text(-10, 5, 'this one is ok') ax.text(-1202255993.82, 5, 'this one fails') plt.show() and also the output of the script run with --verbose-debug? See attached. Darwin Kernel Version 8.11.1: Wed Oct 10 18:23:28 PDT 2007; root:xnu-792.25.20~1/RELEASE_I386 i386 i386 (Mac OS X 10.4.11) I'm running svn r6360 (with my draw_wrapper patch to handle per-artist rasterizing) $HOME=/Users/ebruning CONFIGDIR=/Users/ebruning/.matplotlib matplotlib data path /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/matplotlib/mpl-data loaded rc file /Users/ebruning/.matplotlib/matplotlibrc matplotlib version 0.98.3 verbose.level debug interactive is False units is False platform is darwin loaded modules: ['xml.sax.urlparse', 'distutils', 'matplotlib.errno', 'matplotlib.matplotlib', 'numpy.core.defchararray', 'matplotlib.tempfile', 'distutils.sysconfig', 'ctypes._endian', 'encodings.encodings', 'matplotlib.colors', 'numpy.core.numerictypes', 'numpy.testing.sys', 'numpy.core.info', 'xml', 'numpy.fft.types', 'numpy.ma.operator', 'numpy.ma.cPickle', 'struct', 'numpy.random.info', 'tempfile', 'xml.sax.urllib', 'numpy.linalg', 'matplotlib.threading', 'numpy.testing.operator', 'imp', 'numpy.testing', 'collections', 'numpy.core.umath', '_struct', 'numpy.lib.numpy', 'numpy.core.scalarmath', 'zipimport', 'string', 'numpy.testing.os', 'matplotlib.locale', 'numpy.lib.arraysetops', 'numpy.testing.unittest', 'numpy.lib.math', 'matplotlib.__future__', 'numpy.testing.re', 'itertools', 'numpy.version', 'numpy.lib.re', 'distutils.re', 'ctypes.os', 'numpy.core.os', 'numpy.lib.type_check', 'signal', 'numpy.lib.types', 'numpy.lib._datasource', 'random', 'numpy.ma.extras', 'numpy.fft.fftpack_lite', 'matplotlib.cbook', 'ctypes.ctypes', 'xml.sax.xmlreader', 'numpy.__builtin__', 'numpy.lib.itertools', 'cStringIO', 'numpy.ma.core', 'numpy.numpy', 'matplotlib.StringIO', 'locale', 'numpy.add_newdocs', 'numpy.lib.getlimits', 'ctypes.gestalt', 'xml.sax.saxutils', 'numpy.testing.types', 'numpy.lib.sys', 'encodings', 'numpy.ma.itertools', 'numpy.lib.io', 'numpy.imp', 'threading', 'numpy.testing.decorators', 'matplotlib.warnings', 'matplotlib.string', 'urllib', 'matplotlib.sys', 're', 'numpy.lib._compiled_base', 'numpy.random.mtrand', 'math', 'numpy.fft.helper', 'fcntl', 'numpy.ma.warnings', 'matplotlib.numpy', 'UserDict', 'numpy.lib.function_base', 'distutils.os', 'matplotlib', 'numpy.fft.numpy', 'numpy.lib.ufunclike', 'numpy.lib.info', 'ctypes', 'numpy.lib.warnings', 'ctypes.struct', 'codecs', 'numpy.core._sort', 'numpy.os', '_locale', 'matplotlib.sre_constants', 'socket', 'thread', 'StringIO', 'numpy.core.memmap', 'traceback', 'numpy.testing.warnings', 'weakref', 'numpy.core._internal', 'numpy.fft.fftpack', 'numpy.testing.imp', 'numpy.linalg.lapack_lite', 'distutils.sys', 'os', 'sre_parse', 'numpy.lib.shutil', '__future__', 'matplotlib.copy', 'xml.sax.types', 'matplotlib.traceback', '_sre', 'unittest', 'numpy.core.sys', 'numpy.random', 'numpy.linalg.numpy', '__builtin__', 'numpy.lib.twodim_base', 'matplotlib.re', 'numpy.core.cPickle', 'operator', 'numpy.testing.parametric', 'numpy.core.arrayprint', 'distutils.string', 'numpy.lib.arrayterator', 'ctypes._ctypes', 'ctypes.sys', 'matplotlib.datetime', 'posixpath', 'numpy.lib.financial', 'numpy.core.multiarray', 'errno', '_socket', 'binascii', 'sre_constants', 'datetime', 'numpy.ma', 'xml.sax.handler', 'types', '_ctypes', 'numpy.lib.stride_tricks', 'numpy.core.numpy', 'numpy', 'matplotlib.types', 'numpy.core.defmatrix', 'xml.sax.os', 'cPickle', 'matplotlib.xml', '_codecs', 'numpy.lib.operator', 'numpy.__config__', 'matplotlib.pyparsing', 'gestalt', 'numpy.ma.numpy', 'copy', 'numpy.core.re', 'matplotlib.os', '_types', 'numpy.core.fromnumeric', 'numpy.ctypeslib', 'atexit', 'numpy.lib.scimath', 'numpy.fft', 'numpy.lib', 'numpy.random.numpy', 'posix', 'encodings.aliases', 'matplotlib.fontconfig_pattern', 'exceptions', 'xml.sax._exceptions', 'numpy.core.cStringIO', 'numpy.core.ctypes', 'distutils.distutils', 'copy_reg', 'sre_compile', 'xml.sax', '_random', 'numpy.lib.__future__', 'site', 'numpy.lib.polynomial', 'numpy._import_tools', 'numpy.core.copy_reg', '__main__', 'numpy.fft.info', 'numpy.core.records', 'shutil', 'numpy.lib.cPickle', 'numpy.sys', 'matplotlib.weakref', 'numpy.core._dotblas', 'numpy.testing.traceback', 'strop', 'numpy.testing.numpytest', 'numpy.core.numeric', 'numpy.linalg.info', 'encodings.codecs', 'numpy.core.__svn_version__', 'numpy.ctypes', 'numpy.core', 'matplotlib.rcsetup', 'matplotlib.time', 'xml.sax.codecs', 'stat', '_ssl', 'numpy.lib.utils', 'numpy.lib.index_tricks', 'warnings', 'encodings.types', 'encodings.ascii', 'numpy.lib.shape_base', 'numpy.core.types', 'sys', 'numpy.core.warnings', 'numpy.core.__builtin__',
Re: [Matplotlib-users] plotting labels for each 'artist' in a basemap
On Fri, Nov 21, 2008 at 12:24 PM, John Hunter [EMAIL PROTECTED] wrote: On Fri, Nov 21, 2008 at 10:37 AM, Eric Bruning [EMAIL PROTECTED] wrote: Can you post a complete, free-standing example script which replicates the problem import matplotlib.pyplot as plt f=plt.figure() ax=f.add_subplot(111) ax.plot(range(10)) ax.text(-10, 5, 'this one is ok') ax.text(-1202255993.82, 5, 'this one fails') plt.show() and also the output of the script run with --verbose-debug? See attached. OK, thanks. I can replicate this on one machine (on which python is compiled for 32bit) And I can confirm that my Python is running as 32 bit. My guess is the transformation is putting this int out of bounds on the 32 bit system triggering an exception in the cxx code. From the exception, it looks like the exception is being set in cxx extension code but is not being raised at the time the exception is set, because there is no reason the iteration over the info should be triggering the exception at that time. I fixed backend agg to raise the proper exception so it is at least less confusing -- it now raises ... TypeError: Invalid input arguments to draw_text_image I'm not sure what the desired behavior here is. We could make it fail silently (not plot the text rather than raise) My preference would be to see the error rather than mysteriously not see text. The latter would be more frustrating to debug - hard to track down. A scientific user should probably know that he's overextending the floating point capability, which was my case. I would be interested to see a concise form of John [H2O]'s bug, though - it might get more subtle if it's doing something funny on a map projection, like plotting on the backside of a sphere. Thanks, Eric - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Re: [Matplotlib-users] plotting labels for each 'artist' in a basemap
I just saw a similar error when trying to plot some text; in my case, basemap wasn't involved. The full error dump: /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/matplotlib/text.py in draw(self, renderer) 486 -- 487 for line, wh, x, y in info: 488 x = x + posx 489 y = y + posy TypeError: CXX : Error creating object of type N2Py3IntE My x data were times in seconds calculated relative to a reference date, and reducing the gap cleared up my problem. This thread: http://markmail.org/message/zqfgrshmq3366mtz?q=Error+N2Py3IntE suggests that the error is due to an overflow in the underlying numerics. And ... this is where I reach the end of my expertise. -Eric On Thu, Nov 13, 2008 at 11:38 PM, John [H2O] [EMAIL PROTECTED] wrote: Hello, using matplotlib 0.98 with mpl_toolkit Basemap: I'm trying to create a plot with a series of ellipses over a map. I've followed the tutorial, and can create the same figure as shown here: http://matplotlib.sourceforge.net/users/screenshots.html#ellipses I can also create a series of ellipses over a map. Now I am trying to label each circle using the following snippet: for item in ells: #ells is now a tuple in the form: (Ellipse, (x,y)) and (x,y) is the same as for the Ellipse e = item[0] xy = item[1] ax.add_artist(e) e.set_clip_box(ax.bbox) e.set_alpha(.7) pyplot.text(xy[0],xy[1],e.get_label()) however, for some reason it fails. Can someone provide some ideas on what I am doing wrong? Also, is there more direct way to set the plots so that the labels are drawn? What is strange, is that it seems to work (at least debugging print statements after the loop are printed)... and I can move the text function out of the loop to label the 'last' ellipse... As it is it fails when savefig() or show() are called. The error is: TypeError: CXX : Error creating object of type N2Py3IntE THoughts? Thanks, john -- View this message in context: http://www.nabble.com/plotting-labels-for-each-%27artist%27-in-a-basemap-tp20494609p20494609.html Sent from the matplotlib - users mailing list archive at Nabble.com. - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users
[Matplotlib-users] Scatter plots with date axes
With the following snippet, I expect a vertical line from y=(0, 2) and squares at y=(4, 5, 6) at the specified time. No squares appear with the call to scatter, even though the y axis limits adjust to (0,7) as if something is being plotted. Is this a known limitation of scatter? I'm running the following under ipython -pylab. from datetime import datetime f=figure() ax=f.add_subplot(111) d=datetime(2004,05,26,23,00,00) d=date2num(d) ax.xaxis_date() ax.plot((d,d,d),range(3)) # vertical line ax.scatter((d,d,d),(4,5,6),marker='s') # no symbols plotted draw() Thanks, Eric - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users
[Matplotlib-users] Can I update symbol positions and colors in a collection?
I have scatterplots on several axes that are dynamically updated, and thus I need to keep track of each of the PolyCollection artists that represent the scattered data. I would like to keep the same PolyCollection object but update the positions, colors, etc. of the symbols, possibly changing their total number, something along the lines of Line.set_data. Did I miss a method that would do what I want? I have already looked at removing the collection from the axes and replotting, but for some reason my axis limits get reset when I do so. Thanks, Eric - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users
[Matplotlib-users] Callback after axis limits changed and redraw
I need to trigger some data processing* after the user changes the limits of a plot (e.g., via pan, zoom or the 'home' button). The code below is my proof-of-concept solution to this problem, which I offer for discussion and reference. It was a good practice in learning the events system. I would not be sad if someone were to inform me of more elegant solution. Thanks, Eric *I'm plotting data points in three separate panels (x-y, x-z, and z-y) with shared axes. The data processing replots x-z and z-y to match the data in the x-y view. class accumulator(object): Provides for event callbacks for matplotlib drag/release events and axis limit changes by accumulating a series of event occurrences. Produces a single call to func after a user interacts with the plot. Sample usage: from pylab import figure, show def simple(count): print update , count a = accumulator(simple) f=figure() ax=f.add_subplot(111) plt=ax.plot(range(10)) f.canvas.mpl_connect('draw_event', a.draw_event) f.canvas.mpl_connect('button_release_event', a.mouse_up_event) f.canvas.mpl_connect('button_press_event', a.mouse_down_event) ax.callbacks.connect('xlim_changed', a.axis_limit_changed) ax.callbacks.connect('ylim_changed', a.axis_limit_changed) show() def __init__(self, func): self.func=func self.reset() self.counter = 0 self.mouse_up = False def reset(self): Reset flags after the update function is called. Mouse is tracked separately. self.limits_changed = 0 self.got_draw = False def axis_limit_changed(self, ax): self.limits_changed += 1 self.check_status() def draw_event(self, event): self.got_draw=True self.check_status() def mouse_up_event(self, event): self.mouse_up = True self.check_status() def mouse_down_event(self, event): self.mouse_up = False def both_limits_changed(self): Both x and y limits changed and the mouse is up (not dragging) This condition takes care of the limits being reset outside of a dragging context, such as the view-reset (home) button on the Matplotlib standard toolbar. return (self.limits_changed = 2) self.mouse_up def interaction_complete(self): x, y, or both limits changed, and the mouse is up (not dragging). Also checks if matplotlib has done its final redraw of the screen, which comes after the call to *both* set_xlim and set_ylim have been triggered. The check for the draw event is the crucial step in not producing two calls to self.func. return (self.limits_changed0) self.got_draw self.mouse_up def check_status(self): if self.both_limits_changed() | self.interaction_complete(): self.func(self.counter) self.reset() self.counter += 1 - Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW! Studies have shown that voting for your favorite open source project, along with a healthy diet, reduces your potential for chronic lameness and boredom. Vote Now at http://www.sourceforge.net/community/cca08 ___ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users