On Wed, Dec 21, 2011 at 8:11 AM, Steve Genoud <steve....@gmail.com> wrote: > Hello, > > What would you think of introducing a helper decorator to do the grunt work? > The decorator automatically fetches the axes and feed them to the function. > Also, it adds the figure as first return value. This would also easily > create a common interface for all the functions. > > Is it something that would be useful?
I think it would be useful, but I'm not sure it's worth it (at this stage) do save one or two lines and on having to follow the new convention.
roughly what I'm thinking
plots would be good candidates for decorators because they are more isolated and standalone functions (or methods), time overhead is not a problem
automatic inserting of return arguments makes code inspection more difficult. (My main way of quickly checking some functions in different packages, for example scipy and matplotlib is to call up the source in Spyder.) This will be more difficult or misleading if a decorator changes what is returned.
using the decorator module adds another dependency, or we would have to maintain a copy inside statsmodels
If we add the decorator module, it would be useful to see if we can use the same idea of decorators for consistent interfaces to other functions, e.g. statistical tests, a memoize decorator and similar.
On the other hand, if I remember correctly, Michele Simionato, when he introduced the decorator module, mentioned that there is quite a bit of overhead involved, and these milliseconds here and there for convenience methods might start to add up, or not.
pros and cons, and I'm open either way.
For my personal taste in coding, I don't mind having to write a bit of boiler plate if it makes reading the code easier, but the cache decorator turned out to be very useful.
> > Best, > Steve > > > The code will be something like that, it rests on the decorator module: > > from decorator import decorator > import inspect > > def _insert_in_return_value(to_insert, return_value): > if isinstance(return_value, tuple): > return tuple([to_insert] + list(return_value)) > elif return_value is None: > return to_insert > else: > return to_insert, return_value > > @decorator > def get_axes(f, *args, **kwargs): > ax_index = inspect.getargspec(f).index('ax') > ax = args[ax_index] > > fig, ax = _create_mpl_ax(ax) > > args_out = list(args) > args_out[ax_index] = ax > out = f(*args_out, **kwargs) > return _insert_in_return_value(fig, out) > > > > On Wed, Dec 21, 2011 at 02:24, Fernando Perez <fpere...@gmail.com> wrote: >> >> On Tue, Dec 20, 2011 at 4:23 PM, John Hunter <jdh...@gmail.com> wrote: >> > >> > I think Fernando misspoke. As far as I know, none of the pyplot methods >> > call show, but the do call draw if interactive. >> >> Yes, sorry: draw_if_interactive is what triggers the display. >> >> > I've assumed the notebook inspects the internal pyplot datastructures to >> > see if any figures were created, and if so, inline them. This is how the >> > sphinx plot directive works. But I haven't looked at the ipython internals. >> >> Yup, our inline backend records any calls to draw_if_interactive and >> then flushes out any figures at the end of the execution of user code: >> >> >> https://github.com/ipython/ipython/blob/master/IPython/zmq/pylab/backend_inline.py >> >> (ignore the docstring that says it's SVG for Qt only, now it does SVG >> and png for both the notebook and the qt console, we just need to >> update the docstring). >> >> Cheers, >> >> f > >