Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Bring back the module level 'backend' #6095

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 7, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions lib/matplotlib/backends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@
import warnings


def pylab_setup(backend=None):
backend = matplotlib.get_backend()


def pylab_setup(name=None):
'''return new_figure_manager, draw_if_interactive and show for pyplot

This provides the backend-specific functions that are used by
pyplot to abstract away the difference between interactive backends.

Parameters
----------
backend : str, optional
name : str, optional
The name of the backend to use. If `None`, falls back to
``matplotlib.get_backend()`` (which return ``rcParams['backend']``)

Expand All @@ -26,23 +29,23 @@ def pylab_setup(backend=None):
The module which contains the backend of choice

new_figure_manager : function
Create a new figure manage (roughly maps to GUI window)
Create a new figure manager (roughly maps to GUI window)

draw_if_interactive : function
Redraw the current figure if pyplot is interactive

show : function
Show (and possible block) any unshown figures.
Show (and possibly block) any unshown figures.

'''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling matplotlib.get_backend() in this function was the main point of the PR that broke this. In either case (passed in arg or calling get_backend) the value just needs to be mirrored out to backend. If we only needed to read this value we would not need global as the function would correctly close over it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so if backend is None, use get_backend() and set the module level backend to the result, then keep going with this function?

# Import the requested backend into a generic module object
if backend is None:
backend = matplotlib.get_backend() # validates, to match all_backends

if backend.startswith('module://'):
backend_name = backend[9:]
if name is None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think

global backend
if name is None:
    name = mpl.get_backend()
backend = name

will do the right thing here. It will always defer to an explicitly passed input and then fall back to get_backend which in the end just consults rcparams for the requested backend. Assigning to the variable marked global will change the object that the module-level attribute points at (with out the global it would just bind a local variable).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any guarantee that name, if not None, is anything sensible that you would want to set to backends.backend? For example, say I do pylab_setup('keyboard'). Obviously that's dumb since keyboard is not a valid mpl backend. How should pylab_setup handle this? I would imagine that you might want to do the global backend; backend=name at the very end right before the return?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright. Done.

# validates, to match all_backends
name = matplotlib.get_backend()
if name.startswith('module://'):
backend_name = name[9:]
else:
backend_name = 'backend_' + backend
backend_name = 'backend_' + name
backend_name = backend_name.lower() # until we banish mixed case
backend_name = 'matplotlib.backends.%s' % backend_name.lower()

Expand All @@ -65,20 +68,23 @@ def do_nothing_show(*args, **kwargs):
Your currently selected backend, '%s' does not support show().
Please select a GUI backend in your matplotlibrc file ('%s')
or with matplotlib.use()""" %
(backend, matplotlib.matplotlib_fname()))
(name, matplotlib.matplotlib_fname()))

def do_nothing(*args, **kwargs):
pass

backend_version = getattr(backend_mod, 'backend_version',
'unknown')
backend_version = getattr(backend_mod, 'backend_version', 'unknown')

show = getattr(backend_mod, 'show', do_nothing_show)

draw_if_interactive = getattr(backend_mod, 'draw_if_interactive',
do_nothing)

matplotlib.verbose.report('backend %s version %s' %
(backend, backend_version))
(name, backend_version))

# need to keep a global reference to the backend for compatibility
# reasons. See https://github.com/matplotlib/matplotlib/issues/6092
global backend
backend = name
return backend_mod, new_figure_manager, draw_if_interactive, show