Skip to content

Commit 45bba0b

Browse files
committed
Do not close figures on backend switch.
Do not `close("all")` figures on (allowable) backend switches, e.g. between qt5agg and qt5cairo, or qt5agg and notebook. The NonGuiException message had to change, as the backend returned by get_backend() may no longer match the actual canvas class.
1 parent 5140177 commit 45bba0b

File tree

7 files changed

+23
-9
lines changed

7 files changed

+23
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Auto-closing of figures when switching backend
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
... is deprecated. Explicitly call ``plt.close("all")`` if necessary. In the
4+
future, allowable backend switches (i.e. those that do not swap a GUI event
5+
loop with another one) will not close existing figures.

lib/matplotlib/backend_bases.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
import matplotlib as mpl
4646
from matplotlib import (
4747
_api, backend_tools as tools, cbook, colors, _docstring, text,
48-
_tight_bbox, transforms, widgets, get_backend, is_interactive, rcParams)
48+
_tight_bbox, transforms, widgets, is_interactive, rcParams)
4949
from matplotlib._pylab_helpers import Gcf
5050
from matplotlib.backend_managers import ToolManager
5151
from matplotlib.cbook import _setattr_cm
@@ -2736,8 +2736,8 @@ def show(self):
27362736
# thus warrants a warning.
27372737
return
27382738
raise NonGuiException(
2739-
f"Matplotlib is currently using {get_backend()}, which is a "
2740-
f"non-GUI backend, so cannot show the figure.")
2739+
f"{type(self.canvas).__name__} is non-interactive, and thus cannot be "
2740+
f"shown")
27412741

27422742
def destroy(self):
27432743
pass

lib/matplotlib/pyplot.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -420,11 +420,16 @@ def draw_if_interactive():
420420
# Need to keep a global reference to the backend for compatibility reasons.
421421
# See https://github.com/matplotlib/matplotlib/issues/6092
422422
matplotlib.backends.backend = newbackend # type: ignore[attr-defined]
423+
423424
if not cbook._str_equal(old_backend, newbackend):
425+
if get_fignums():
426+
_api.warn_deprecated("3.8", message=(
427+
"Auto-close()ing of figures upon backend switching is deprecated since "
428+
"%(since)s and will be removed %(removal)s. To suppress this warning, "
429+
"explicitly call plt.close('all') first."))
424430
close("all")
425431

426-
# make sure the repl display hook is installed in case we become
427-
# interactive
432+
# Make sure the repl display hook is installed in case we become interactive.
428433
install_repl_displayhook()
429434

430435

lib/matplotlib/testing/conftest.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ def mpl_test_settings(request):
7575
try:
7676
yield
7777
finally:
78-
matplotlib.use(prev_backend)
78+
if backend is not None:
79+
plt.close("all")
80+
matplotlib.use(prev_backend)
7981

8082

8183
@pytest.fixture

lib/matplotlib/tests/test_backend_bases.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,13 @@ def test_non_gui_warning(monkeypatch):
8585
with pytest.warns(UserWarning) as rec:
8686
plt.show()
8787
assert len(rec) == 1
88-
assert ('Matplotlib is currently using pdf, which is a non-GUI backend'
88+
assert ('FigureCanvasPdf is non-interactive, and thus cannot be shown'
8989
in str(rec[0].message))
9090

9191
with pytest.warns(UserWarning) as rec:
9292
plt.gcf().show()
9393
assert len(rec) == 1
94-
assert ('Matplotlib is currently using pdf, which is a non-GUI backend'
94+
assert ('FigureCanvasPdf is non-interactive, and thus cannot be shown'
9595
in str(rec[0].message))
9696

9797

lib/matplotlib/tests/test_backends_interactive.py

+1
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ def check_alt_backend(alt_backend):
167167
fig = plt.figure()
168168
assert (type(fig.canvas).__module__ ==
169169
f"matplotlib.backends.backend_{alt_backend}")
170+
plt.close("all")
170171

171172
if importlib.util.find_spec("cairocffi"):
172173
check_alt_backend(backend[:-3] + "cairo")

lib/matplotlib/tests/test_pyplot.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,8 @@ def test_switch_backend_no_close():
439439
assert len(plt.get_fignums()) == 2
440440
plt.switch_backend('agg')
441441
assert len(plt.get_fignums()) == 2
442-
plt.switch_backend('svg')
442+
with pytest.warns(mpl.MatplotlibDeprecationWarning):
443+
plt.switch_backend('svg')
443444
assert len(plt.get_fignums()) == 0
444445

445446

0 commit comments

Comments
 (0)