Skip to content

Commit

Permalink
Merge pull request matplotlib#23291 from anntzer/udif
Browse files Browse the repository at this point in the history
API: In the new/simplified backend API, don't customize draw_if_interactive.
  • Loading branch information
tacaswell authored Jul 11, 2022
2 parents f06c2c3 + 2806e6d commit 8dc14e0
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 38 deletions.
4 changes: 4 additions & 0 deletions doc/api/next_api_changes/removals/23291-AL.rst
Original file line number Diff line number Diff line change
@@ -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.
29 changes: 3 additions & 26 deletions lib/matplotlib/backends/backend_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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):
Expand Down
22 changes: 14 additions & 8 deletions lib/matplotlib/pyplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
14 changes: 10 additions & 4 deletions lib/matplotlib/tests/test_backend_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit 8dc14e0

Please sign in to comment.