As we discussed last time something similar came up, I think it's not a good idea to use a decorator for this.
We get all the negative effects of a decorator, and it is just one line of code to do the draw if interactive before the return.
-1 on this. Personally I don't want figures to pop up before I tell them to. More importantly, both Fernando and John Hunter advised against using draw_if_interactive in this thread: https://groups.google.com/forum/#!msg/pystatsmodels/biNlCvJPNNY/BT7bQJmOa1cJ
It messes up the IPython notebook apparently.
ENH: Decorate plot functions with draw if interactive calls
Hmm. Ok. Well this is a bit annoying then for people who do choose to work in interactive mode and not with qtconsole or the notebooks. I'm often sitting there wondering why changes never show up on plots compared to the R experience of updating on command. My understanding is that matplotlib uses this internally in pyplot and IPython catches it, so it's handled but the recommendation is not to use it? Also, calling draw_if_interactive won't make your figures pop up if you're not in interactive mode.
ENH: Use functools.wraps in decorator
If this is what you always want in an IPython console, you can add it to your IPython startup config right? Or type it once on the command line. Adding this to every plot in statsmodels just seems like the wrong solution.
Yes, I have interactive = True in my mpl or ipython config. But when I have, say, a scatter plot of points already, then I pass this axes to abline_plot, I expect that my regression line will just show up when it returns the new fig. But the plot won't get updated until I import and call draw_if_interactive. If you don't have interactive = True, then the call is innocuous. I brought it up on ipython-user. Since the notebooks have been through many more iterations since that discussion, I'm hoping that it's handled now. It seems like a useful feature to me.
OK, let's see what the IPython folks say then.
I never use interactive, so I'm don't have a personal preference either way.
I think I remember now from the discussion that one reason not to import pyplot is if there is no displayed backend.
(But I'm not sure I remember correctly.)
this would mean protecting the import of pyplot (beyond the matplotlib import)
If there is a real desire to have both behaviors, then one possibility would be to add our own draw_if_interactive global option, that can be turned off even if matplotlib is in interactive mode.
I asked on the ipython list. The answer I got did not really clear anything up (or did it now that I reread?). It seems that issue is with show. I'm not proposing calling show. I'm just proposing updating an axes on interaction. I also don't think there's a performance hit unless the user is actually in interactive mode, which means there's no show call anyway. Still don't see how this is a problem and haven't been told that there actually is one yet. Here's the thread
Maybe I should ask on mpl-user.
Looking back at John Hunter's recommendation
"Finally, I would avoid anything in pyplot (gca, gcf) because you can't
assume your user has imported pyplot (eg they may be embedding your
stats plots in a GUI and importing pyplot could cause conflicting GUI
mainloops). I would only import pyplot if the axes is None"
I think the problem is if we need to import if_interactive from pyplot.
The recommendation was to make all pyplot imports part of an optional codepath. I think the examples are some embedding code and web servers, that should run with only the object oriented interface.
(I definitely don't like the decorator solution.)
as I mentioned before, we can use our own global settings, and only import from pyplot if "can_use_pyplot" (or something) is true.
I'm not using gca or gcf or anything that assumes you've imported pyplot and are working this way. If you're not, then the call is innocuous AFAICT. In a GUI or as an embedded plot, interactive will be False, so nothing happens. We can assume the user has pyplot because they have matplotlib to even use this part of the code. There's nothing in draw_if_interactive that assumes that the plot has been created using the pyplot commands.
Decorators are not evil. This isn't that magical and it's the easiest way to get this behavior for all the plotting functions without having to copy and paste a bunch of code.
Again, I really don't know the internals of MPL well so I don't want to come off like I do and am arguing hard in favor of this, but I've still yet to hear a definitive answer that this can produce problems. I'll ask on MPL.
Closing this because it sounds dead in the water. I'm not convinced there are actual side effects though. (And decorators are useful sometimes.)