1from __future__ import (absolute_import, division, print_function,
2                        unicode_literals)
3
4import six
5
6import matplotlib
7import inspect
8import traceback
9import warnings
10import logging
11
12_log = logging.getLogger(__name__)
13
14backend = matplotlib.get_backend()
15# the `str` calls here are to make non-ascii paths work on python2
16_backend_loading_tb = str("").join(
17    line for line in traceback.format_stack()
18    # Filter out line noise from importlib line.
19    if not line.startswith(str('  File "<frozen importlib._bootstrap')))
20
21
22def pylab_setup(name=None):
23    '''return new_figure_manager, draw_if_interactive and show for pyplot
24
25    This provides the backend-specific functions that are used by
26    pyplot to abstract away the difference between interactive backends.
27
28    Parameters
29    ----------
30    name : str, optional
31        The name of the backend to use.  If `None`, falls back to
32        ``matplotlib.get_backend()`` (which return :rc:`backend`).
33
34    Returns
35    -------
36    backend_mod : module
37        The module which contains the backend of choice
38
39    new_figure_manager : function
40        Create a new figure manager (roughly maps to GUI window)
41
42    draw_if_interactive : function
43        Redraw the current figure if pyplot is interactive
44
45    show : function
46        Show (and possibly block) any unshown figures.
47
48    '''
49    # Import the requested backend into a generic module object
50    if name is None:
51        # validates, to match all_backends
52        name = matplotlib.get_backend()
53    if name.startswith('module://'):
54        backend_name = name[9:]
55    else:
56        backend_name = 'backend_' + name
57        backend_name = backend_name.lower()  # until we banish mixed case
58        backend_name = 'matplotlib.backends.%s' % backend_name.lower()
59
60    # the last argument is specifies whether to use absolute or relative
61    # imports. 0 means only perform absolute imports.
62    backend_mod = __import__(backend_name, globals(), locals(),
63                             [backend_name], 0)
64
65    # Things we pull in from all backends
66    new_figure_manager = backend_mod.new_figure_manager
67
68    # image backends like pdf, agg or svg do not need to do anything
69    # for "show" or "draw_if_interactive", so if they are not defined
70    # by the backend, just do nothing
71    def do_nothing_show(*args, **kwargs):
72        frame = inspect.currentframe()
73        fname = frame.f_back.f_code.co_filename
74        if fname in ('<stdin>', '<ipython console>'):
75            warnings.warn("""
76Your currently selected backend, '%s' does not support show().
77Please select a GUI backend in your matplotlibrc file ('%s')
78or with matplotlib.use()""" %
79                          (name, matplotlib.matplotlib_fname()))
80
81    def do_nothing(*args, **kwargs):
82        pass
83
84    backend_version = getattr(backend_mod, 'backend_version', 'unknown')
85
86    show = getattr(backend_mod, 'show', do_nothing_show)
87
88    draw_if_interactive = getattr(backend_mod, 'draw_if_interactive',
89                                  do_nothing)
90
91    _log.debug('backend %s version %s', name, backend_version)
92
93    # need to keep a global reference to the backend for compatibility
94    # reasons. See https://github.com/matplotlib/matplotlib/issues/6092
95    global backend
96    backend = name
97    return backend_mod, new_figure_manager, draw_if_interactive, show
98