Skip to content

Commit 2806e6d

Browse files
committed
In the new/simplified backend API, don't customize draw_if_interactive.
The customization point is not really needed (it can go into the canvas constructor or manager.show or a few other places), but removing support for it would be a bit tricky if not coupled with the introduction of a new API (manager_class). This way, we can simply say "if you want to use the new API, then you cannot customize draw_if_interactive". backend_template gets updated without deprecation as the point of that backend is really to be documentation for what a backend module is; moreover, putting a deprecation on new_figure_manager (for example) would actually be counter-productive as pyplot would still try to call that function (and thus emit a warning, even though the backend itself is not deprecated).
1 parent dab648a commit 2806e6d

File tree

4 files changed

+31
-38
lines changed

4 files changed

+31
-38
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
``backend_template.new_figure_manager``, ``backend_template.new_figure_manager_given_figure``, and ``backend_template.draw_if_interactive``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
... have been removed, as part of the introduction of the simplified backend
4+
API.

lib/matplotlib/backends/backend_template.py

+3-26
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,6 @@ class GraphicsContextTemplate(GraphicsContextBase):
136136
########################################################################
137137

138138

139-
def draw_if_interactive():
140-
"""
141-
For image backends - is not required.
142-
For GUI backends - this should be overridden if drawing should be done in
143-
interactive python mode.
144-
"""
145-
146-
147139
def show(*, block=None):
148140
"""
149141
For image backends - is not required.
@@ -156,24 +148,6 @@ def show(*, block=None):
156148
pass
157149

158150

159-
def new_figure_manager(num, *args, FigureClass=Figure, **kwargs):
160-
"""Create a new figure manager instance."""
161-
thisFig = FigureClass(*args, **kwargs)
162-
return new_figure_manager_given_figure(num, thisFig)
163-
164-
165-
def new_figure_manager_given_figure(num, figure):
166-
"""Create a new figure manager instance for the given figure."""
167-
# If a main-level app must be created, this is the usual place to do it
168-
# -- see the wx and tk backends for examples (the default implementation
169-
# of new_figure_manager defers to new_figure_manager_given_figure, so it
170-
# also benefits from this instantiation). Not all GUIs require explicit
171-
# instantiation of a main-level app (e.g., backend_gtk3) for pylab.
172-
canvas = FigureCanvasTemplate(figure)
173-
manager = FigureManagerTemplate(canvas, num)
174-
return manager
175-
176-
177151
class FigureManagerTemplate(FigureManagerBase):
178152
"""
179153
Helper class for pyplot mode, wraps everything up into a neat bundle.
@@ -199,6 +173,9 @@ class methods button_press_event, button_release_event,
199173
A high-level Figure instance
200174
"""
201175

176+
# The instantiated manager class. For further customization,
177+
# ``FigureManager.create_with_canvas`` can also be overridden; see the
178+
# wx-based backends for an example.
202179
manager_class = FigureManagerTemplate
203180

204181
def draw(self):

lib/matplotlib/pyplot.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -274,13 +274,11 @@ def switch_backend(newbackend):
274274
"framework, as {!r} is currently running".format(
275275
newbackend, required_framework, current_framework))
276276

277-
# Load the new_figure_manager(), draw_if_interactive(), and show()
278-
# functions from the backend.
277+
# Load the new_figure_manager() and show() functions from the backend.
279278

280279
# Classically, backends can directly export these functions. This should
281280
# keep working for backcompat.
282281
new_figure_manager = getattr(backend_mod, "new_figure_manager", None)
283-
# draw_if_interactive = getattr(backend_mod, "draw_if_interactive", None)
284282
# show = getattr(backend_mod, "show", None)
285283
# In that classical approach, backends are implemented as modules, but
286284
# "inherit" default method implementations from backend_bases._Backend.
@@ -290,8 +288,9 @@ class backend_mod(matplotlib.backend_bases._Backend):
290288
locals().update(vars(backend_mod))
291289

292290
# However, the newer approach for defining new_figure_manager (and, in
293-
# the future, draw_if_interactive and show) is to derive them from canvas
294-
# methods. In that case, also update backend_mod accordingly.
291+
# the future, show) is to derive them from canvas methods. In that case,
292+
# also update backend_mod accordingly; also, per-backend customization of
293+
# draw_if_interactive is disabled.
295294
if new_figure_manager is None:
296295
def new_figure_manager_given_figure(num, figure):
297296
return canvas_class.new_manager(figure, num)
@@ -300,9 +299,16 @@ def new_figure_manager(num, *args, FigureClass=Figure, **kwargs):
300299
fig = FigureClass(*args, **kwargs)
301300
return new_figure_manager_given_figure(num, fig)
302301

302+
def draw_if_interactive():
303+
if matplotlib.is_interactive():
304+
manager = _pylab_helpers.Gcf.get_active()
305+
if manager:
306+
manager.canvas.draw_idle()
307+
303308
backend_mod.new_figure_manager_given_figure = \
304309
new_figure_manager_given_figure
305310
backend_mod.new_figure_manager = new_figure_manager
311+
backend_mod.draw_if_interactive = draw_if_interactive
306312

307313
_log.debug("Loaded backend %s version %s.",
308314
newbackend, backend_mod.backend_version)
@@ -762,9 +768,9 @@ def figure(num=None, # autoincrement if None, else integer from 1-N
762768
763769
Notes
764770
-----
765-
Newly created figures will be passed to the
766-
`~.backend_template.new_figure_manager` function provided by the current
767-
backend, which will install a canvas and a manager on the figure.
771+
Newly created figures are passed to the `~.FigureCanvasBase.new_manager`
772+
method or the `new_figure_manager` function provided by the current
773+
backend, which install a canvas and a manager on the figure.
768774
769775
If you are creating many figures, make sure you explicitly call
770776
`.pyplot.close` on the figures you are not using, because this will

lib/matplotlib/tests/test_backend_template.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,22 @@
88
import matplotlib as mpl
99
from matplotlib import pyplot as plt
1010
from matplotlib.backends import backend_template
11+
from matplotlib.backends.backend_template import (
12+
FigureCanvasTemplate, FigureManagerTemplate)
1113

1214

1315
def test_load_template():
1416
mpl.use("template")
15-
assert type(plt.figure().canvas) == backend_template.FigureCanvasTemplate
17+
assert type(plt.figure().canvas) == FigureCanvasTemplate
1618

1719

18-
def test_new_manager(monkeypatch):
20+
def test_load_old_api(monkeypatch):
1921
mpl_test_backend = SimpleNamespace(**vars(backend_template))
20-
del mpl_test_backend.new_figure_manager
22+
mpl_test_backend.new_figure_manager = (
23+
lambda num, *args, FigureClass=mpl.figure.Figure, **kwargs:
24+
FigureManagerTemplate(
25+
FigureCanvasTemplate(FigureClass(*args, **kwargs)), num))
2126
monkeypatch.setitem(sys.modules, "mpl_test_backend", mpl_test_backend)
2227
mpl.use("module://mpl_test_backend")
23-
assert type(plt.figure().canvas) == backend_template.FigureCanvasTemplate
28+
assert type(plt.figure().canvas) == FigureCanvasTemplate
29+
plt.draw_if_interactive()

0 commit comments

Comments
 (0)