I've expanded a bit on my previous solution for pre/post draw method
callbacks to add a registry which can be used to connect up arbitrary
callback functions.

The solution above is easy to adapt to other functions that might need
a callback, such as (to pick a random example) set_xlim.

See the attached example, which shows the functionality in action.
I've also shown how to handle the calls to start/stop raster in the
renderer that were my previous use case.

-Eric B
from matplotlib.cbook import CallbackRegistry
from matplotlib.axes import Axes

class Hooks(object):
    
    def __init__(self):
        signals = ('before_draw', 'after_draw')
        self.callbacks = CallbackRegistry(signals)        
        
    def before_after_draw(self, draw):    
        """
        Decorator for Artist.draw method. Provides routines
        that run before and after the draw call. The before and after functions
        are useful for changing artist-dependant renderer attributes or making
        other setup function calls, such as starting and flushing a mixed-mode
        renderer. 
        """
        def before(artist, renderer):
            self.callbacks.process('before_draw', artist, renderer)

        def after(artist, renderer):
            self.callbacks.process('after_draw', artist, renderer)

        def draw_wrapper(artist, renderer):
            before(artist, renderer)    
            draw(artist, renderer)
            after(artist, renderer)

        # "safe wrapping" to exactly replicate anything we haven't overridden above
        draw_wrapper.__name__ = draw.__name__
        draw_wrapper.__dict__ = draw.__dict__
        draw_wrapper.__doc__  = draw.__doc__
        return draw_wrapper
        
def greeter(artist, renderer):
    print 'Hello, ', artist, '. You will be rendered tonight by', renderer
    
def benediction(artist, renderer):
    print 'Good night, ', artist, '. You were rendered tonight by', renderer

def start_raster_mode(artist, renderer):
    if artist.get_rasterized():
        renderer.start_rasterizing()
        
def stop_raster_mode(artist, renderer):
    if artist.get_rasterized():
        renderer.stop_rasterizing()

hooks = Hooks()
hooks.callbacks.connect('before_draw', greeter)
hooks.callbacks.connect('after_draw', benediction)
hooks.callbacks.connect('before_draw', start_raster_mode)
hooks.callbacks.connect('after_draw', stop_raster_mode)

class WrappedAxes(Axes):
    """ In real life, the Axes.draw() method would be decorated directly, 
        but this serves for the purposes of this demo. """

    @hooks.before_after_draw
    def draw(self, renderer):
        super(WrappedAxes, self).draw(renderer)
    

import matplotlib.pyplot as plt

fig = plt.figure()
fig.clf()
ax = fig.add_axes(WrappedAxes(fig, (0.1,0.1,0.8,0.8)))
ax.plot(range(10))
plt.show()
-------------------------------------------------------------------------
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=100&url=/
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to