John Hunter wrote:
> Hey Eric, I'm CC-ing the devel list because some of this has
> potentially far reaching consequences.
>
>>>>>> "Eric" == Eric Firing <[EMAIL PROTECTED]> writes:
>
> Eric> In connection with the colorbar sizing problem I have been
> Eric> thinking about adding a function list to axes, with the
> Eric> functions to be executed early in the draw() method, to
> Eric> handle this sort of thing. Using this mechanism to handle
>
> I think this is a very nice idea -- I saw a talk at pycon one year about
> the utility of adding hooks, eg before_somefunc_hook and after_somefunc_hook
> that are customizable *for every function in your API*. The questions are
>
> 1) what is the right data structure -- a single callable, a
> sequence, or a dictionary registry with connect/disconnect
> semantics (eg the backend event callback handler)
>
> 2) what is the signature (see below)
>
> 3) which artists should support it
>
> Most elegant, but most expensive, is something like a ordered
> dictionary which is supported for every artist. By renaming all the
> artist draw methods _draw, we can do this quite simply in
> backend_bases.Renderer with
>
> def draw(self, renderer):
> for func in self.before_draw_hook.ordered_values():
> func(self, renderer)
>
> self._draw(renderer)
>
> for func in self.after_draw_hook.ordered_values():
> func(self, renderer)
>
Nice, simple, elegant, but it doesn't quite match what I had in mind for
axes. I was thinking that the place to put the hook call is inside the
draw() method, so it can take advantage of the intial work done there:
getting a cached renderer, checking for visibility. Maybe this doesn't
matter.
Also, looking at backend_bases, I can't figure out where this goes.
There is a RendererBase class, but it doesn't have a draw method. And
there is a FigureCanvasBase, but its draw method is overridden by each
backend. What am I missing?
>
> I think this could be really useful and would help handle problems
> that crop up all the time -- how to handle physical layout problems
> where we need the renderer to get size information like you are
> experiencing with colorbar. This problem also crops up in a lot of
> text layout problems. Unfortunately, draw time layout creates other
> problems (sometimes users want this info at the API level), and order
> effects becomes very important and potentially complicated. But that
> said, given the current architecture, something like this would be a
> definite improvement.
>
> I'm inclined to use an ordered dictionary because one wants the
> connect/disconnect semantics that keys make easy, and because ordering
> matters. There is a python cookbook recipe for an ordered dictionary,
> and we could easily roll our own. Because the calls are potentially
> expensive, we might want an optimization like
>
I agree, an ordered dictionary is ideal if one needs the option of
multiple functions being executed. I would probably have it inherit
from list and tack on the dictionary; I think this might make for the
fastest cycling through the list, and that is the place where speed is
needed.
> class MyOrderedDictionary:
> def __init__(blah):
> self.isempty = True
>
>
> so we can do
>
> def draw(renderer):
> if not self.before_draw_hook.isempty:
> for func in self.before_draw_hook.ordered_values():
> func(self, renderer)
>
> self._draw(renderer)
>
> if not self.after_draw_hook.isempty:
> for func in self.after_draw_hook.ordered_values():
> func(self, renderer)
>
> Since 99% of the time I guess these will be empty and then we are just
> adding a few attribute lookups and a boolean check for each draw.
Detail:
Maybe it would be simpler and faster to initialize like this:
self.before_draw_hook=None
and have
def register_before_draw(self, name, func):
if self.before_draw_hook is None:
self.before_draw_hook = OrderedDictionary()
self.before_draw_hook.append(name, func)
It saves one attribute lookup at draw time.
Larger picture:
Looking at the axes draw method, I am wondering whether a more general
application of an OrderedDictionary (or ListDict, or whatever) wouldn't
be a better approach. Why should there be before_draw_hook, draw, and
after_draw_hook, with a big list generation and sorting operation at
draw time? Could everything be done by having artists register all
draw-time functions in a single ListDict, with sufficient ordering
information to keep everything straight? That's pretty vague, and there
is a lot I don't understand--but it just seems like there is an
opportunity here for simplifying the overall structure with improved
flexibility and no loss of speed. (Again, some kind of result-caching
and need-for-recomputation-signalling would be needed.)
Eric
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Matplotlib-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel