From: Benjamin R. <ben...@ou...> - 2012-07-20 20:24:16
|
On Fri, Jul 20, 2012 at 3:20 PM, Eric Firing <ef...@ha...> wrote: > On 2012/07/20 9:34 AM, Ryan May wrote: > > Hi, > > > > I'm here at the SciPy sprints trying to fix switching inline/gui for > > the ipython notebook. I've noticed something weird about > > matplotlib.use() : > > > > if 'matplotlib.backends' in sys.modules: > > if warn: warnings.warn(_use_error_msg) > > return > > if arg.startswith('module://'): > > name = arg > > else: > > # Lowercase only non-module backend names (modules are > case-sensitive) > > arg = arg.lower() > > name = validate_backend(arg) > > rcParams['backend'] = name > > > > Notice the return if it finds the module loaded. This return basically > > makes it impossible to make use() have any effect one backends has > > been loaded. However, matplotlib.pyplot.switch_backend(). Eric added > > this in 2008 as a bug fix, but no more detail than that. Does anyone > > have a problem putting the return with the warning? Therefore if you > > pass warn=False, you can actually make the setting take effect, but > > the average user won't accidentally shoot their foot off. Something > > like: > > > > if 'matplotlib.backends' in sys.modules: > > if warn: > > warnings.warn(_use_error_msg) > > return > > This would be defeating the basic idea: use() is *only* designed to take > effect *once*. If you need to switch backends, it takes more than what > use() does, hence the need for switch_backend(). (But see below.) > > The warn=False invocation of use, with the return statement were it is > now, is for the case where you may have a script or module that > specifies a backend (in case it is the first or only import of > matplotlib), but that may itself be imported or called by something else > that has already imported matplotlib and set the backend. In this case > we want the warning to be suppressed, which is all the warn=False flag > is supposed to do. I use this myself. > > So it looks like the problem is that switch_backends is broken because > what it needs matplotlib.use to do is go ahead and make the switch. This > could be done by adding a force=True kwarg (default would be False) to > matplotlib.use, or by deleting the reference to the backends module from > sys.modules in switch_backends before calling matplotlib.use. A > variation would be to use the force kwarg and to include the > switch_backends logic, or at least the reload line, in matplotlib.use. > That probably makes sense: add the force kwarg, and when the module is > replaced, reload it immediately within matplotlib.use. Then > pyplot.switch_backends only needs to do the pyplot-specific operations. > I think that is the cleanest solution. > > Eric > > I like the "force" idea very much. It means exactly what it says. Ben Root |