diff --git a/doc/api/next_api_changes/removals/23291-AL.rst b/doc/api/next_api_changes/removals/23291-AL.rst new file mode 100644 index 000000000000..60a2260fba03 --- /dev/null +++ b/doc/api/next_api_changes/removals/23291-AL.rst @@ -0,0 +1,4 @@ +``backend_template.new_figure_manager``, ``backend_template.new_figure_manager_given_figure``, and ``backend_template.draw_if_interactive`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +... have been removed, as part of the introduction of the simplified backend +API. diff --git a/lib/matplotlib/backends/backend_template.py b/lib/matplotlib/backends/backend_template.py index ebb9b413f5c0..eb3362d05383 100644 --- a/lib/matplotlib/backends/backend_template.py +++ b/lib/matplotlib/backends/backend_template.py @@ -136,14 +136,6 @@ class GraphicsContextTemplate(GraphicsContextBase): ######################################################################## -def draw_if_interactive(): - """ - For image backends - is not required. - For GUI backends - this should be overridden if drawing should be done in - interactive python mode. - """ - - def show(*, block=None): """ For image backends - is not required. @@ -156,24 +148,6 @@ def show(*, block=None): pass -def new_figure_manager(num, *args, FigureClass=Figure, **kwargs): - """Create a new figure manager instance.""" - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """Create a new figure manager instance for the given figure.""" - # If a main-level app must be created, this is the usual place to do it - # -- see the wx and tk backends for examples (the default implementation - # of new_figure_manager defers to new_figure_manager_given_figure, so it - # also benefits from this instantiation). Not all GUIs require explicit - # instantiation of a main-level app (e.g., backend_gtk3) for pylab. - canvas = FigureCanvasTemplate(figure) - manager = FigureManagerTemplate(canvas, num) - return manager - - class FigureManagerTemplate(FigureManagerBase): """ Helper class for pyplot mode, wraps everything up into a neat bundle. @@ -199,6 +173,9 @@ class methods button_press_event, button_release_event, A high-level Figure instance """ + # The instantiated manager class. For further customization, + # ``FigureManager.create_with_canvas`` can also be overridden; see the + # wx-based backends for an example. manager_class = FigureManagerTemplate def draw(self): diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 193491f8a9ef..418f7b06ecd9 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -274,13 +274,11 @@ def switch_backend(newbackend): "framework, as {!r} is currently running".format( newbackend, required_framework, current_framework)) - # Load the new_figure_manager(), draw_if_interactive(), and show() - # functions from the backend. + # Load the new_figure_manager() and show() functions from the backend. # Classically, backends can directly export these functions. This should # keep working for backcompat. new_figure_manager = getattr(backend_mod, "new_figure_manager", None) - # draw_if_interactive = getattr(backend_mod, "draw_if_interactive", None) # show = getattr(backend_mod, "show", None) # In that classical approach, backends are implemented as modules, but # "inherit" default method implementations from backend_bases._Backend. @@ -290,8 +288,9 @@ class backend_mod(matplotlib.backend_bases._Backend): locals().update(vars(backend_mod)) # However, the newer approach for defining new_figure_manager (and, in - # the future, draw_if_interactive and show) is to derive them from canvas - # methods. In that case, also update backend_mod accordingly. + # the future, show) is to derive them from canvas methods. In that case, + # also update backend_mod accordingly; also, per-backend customization of + # draw_if_interactive is disabled. if new_figure_manager is None: def new_figure_manager_given_figure(num, figure): return canvas_class.new_manager(figure, num) @@ -300,9 +299,16 @@ def new_figure_manager(num, *args, FigureClass=Figure, **kwargs): fig = FigureClass(*args, **kwargs) return new_figure_manager_given_figure(num, fig) + def draw_if_interactive(): + if matplotlib.is_interactive(): + manager = _pylab_helpers.Gcf.get_active() + if manager: + manager.canvas.draw_idle() + backend_mod.new_figure_manager_given_figure = \ new_figure_manager_given_figure backend_mod.new_figure_manager = new_figure_manager + backend_mod.draw_if_interactive = draw_if_interactive _log.debug("Loaded backend %s version %s.", newbackend, backend_mod.backend_version) @@ -762,9 +768,9 @@ def figure(num=None, # autoincrement if None, else integer from 1-N Notes ----- - Newly created figures will be passed to the - `~.backend_template.new_figure_manager` function provided by the current - backend, which will install a canvas and a manager on the figure. + Newly created figures are passed to the `~.FigureCanvasBase.new_manager` + method or the `new_figure_manager` function provided by the current + backend, which install a canvas and a manager on the figure. If you are creating many figures, make sure you explicitly call `.pyplot.close` on the figures you are not using, because this will diff --git a/lib/matplotlib/tests/test_backend_template.py b/lib/matplotlib/tests/test_backend_template.py index 31ab644f248f..7afe8bae69a9 100644 --- a/lib/matplotlib/tests/test_backend_template.py +++ b/lib/matplotlib/tests/test_backend_template.py @@ -8,16 +8,22 @@ import matplotlib as mpl from matplotlib import pyplot as plt from matplotlib.backends import backend_template +from matplotlib.backends.backend_template import ( + FigureCanvasTemplate, FigureManagerTemplate) def test_load_template(): mpl.use("template") - assert type(plt.figure().canvas) == backend_template.FigureCanvasTemplate + assert type(plt.figure().canvas) == FigureCanvasTemplate -def test_new_manager(monkeypatch): +def test_load_old_api(monkeypatch): mpl_test_backend = SimpleNamespace(**vars(backend_template)) - del mpl_test_backend.new_figure_manager + mpl_test_backend.new_figure_manager = ( + lambda num, *args, FigureClass=mpl.figure.Figure, **kwargs: + FigureManagerTemplate( + FigureCanvasTemplate(FigureClass(*args, **kwargs)), num)) monkeypatch.setitem(sys.modules, "mpl_test_backend", mpl_test_backend) mpl.use("module://mpl_test_backend") - assert type(plt.figure().canvas) == backend_template.FigureCanvasTemplate + assert type(plt.figure().canvas) == FigureCanvasTemplate + plt.draw_if_interactive()