From 080f8ac7b995662adc70677aa8d8d3b4f08864c8 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Thu, 3 Sep 2026 12:01:01 +0200 Subject: [PATCH 1/5] fix plt.show --- src/plopp/backends/matplotlib/utils.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/plopp/backends/matplotlib/utils.py b/src/plopp/backends/matplotlib/utils.py index 00b35787..d76b64b1 100644 --- a/src/plopp/backends/matplotlib/utils.py +++ b/src/plopp/backends/matplotlib/utils.py @@ -6,6 +6,7 @@ import matplotlib as mpl import matplotlib.pyplot as plt +from matplotlib._pylab_helpers import Gcf from matplotlib.lines import Line2D @@ -62,6 +63,11 @@ def is_widget_backend() -> bool: return any(b in backend for b in ('ipympl', 'nbagg', 'notebook', 'widget')) +def _next_free_figure_num() -> int: + used = Gcf.figs + return 1 if not used else max(used) + 1 + + def make_figure(*args, **kwargs) -> plt.Figure: """ Create a new figure. @@ -80,7 +86,11 @@ def make_figure(*args, **kwargs) -> plt.Figure: if is_interactive_backend(): # Create a manager for the figure, which makes it interactive, as well as # making it possible to show the figure from the terminal. - plt._get_backend_mod().new_figure_manager_given_figure(1, fig) + manager = plt._get_backend_mod().new_figure_manager_given_figure( + _next_free_figure_num(), fig + ) + # Register with pyplot global figure manager registry so plt.show() sees it. + Gcf.set_active(manager) return fig From c0bab340d563c552aac6aaf2a1835e8976eb6501 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Thu, 3 Sep 2026 12:26:57 +0200 Subject: [PATCH 2/5] do not set manager for widget backends --- src/plopp/backends/matplotlib/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plopp/backends/matplotlib/utils.py b/src/plopp/backends/matplotlib/utils.py index d76b64b1..9fc8e83f 100644 --- a/src/plopp/backends/matplotlib/utils.py +++ b/src/plopp/backends/matplotlib/utils.py @@ -90,7 +90,8 @@ def make_figure(*args, **kwargs) -> plt.Figure: _next_free_figure_num(), fig ) # Register with pyplot global figure manager registry so plt.show() sees it. - Gcf.set_active(manager) + if not is_widget_backend(): + Gcf.set_active(manager) return fig From 6e2765e622c8e7e8484c3980dd6abf84b2fe8bb7 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Thu, 3 Sep 2026 12:29:11 +0200 Subject: [PATCH 3/5] add comment --- src/plopp/backends/matplotlib/utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plopp/backends/matplotlib/utils.py b/src/plopp/backends/matplotlib/utils.py index 9fc8e83f..629b3742 100644 --- a/src/plopp/backends/matplotlib/utils.py +++ b/src/plopp/backends/matplotlib/utils.py @@ -90,6 +90,9 @@ def make_figure(*args, **kwargs) -> plt.Figure: _next_free_figure_num(), fig ) # Register with pyplot global figure manager registry so plt.show() sees it. + # Note that we do not want to do this for interactive jupyter backends as it + # will cause the figure to be automatically displayed in the notebook, + # which we do not want. if not is_widget_backend(): Gcf.set_active(manager) return fig From e07b77454eb64ef6dab2a3c7707e2e25509194eb Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Tue, 8 Sep 2026 10:24:06 +0200 Subject: [PATCH 4/5] use plt.figure when not widget instead --- src/plopp/backends/matplotlib/utils.py | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/plopp/backends/matplotlib/utils.py b/src/plopp/backends/matplotlib/utils.py index 629b3742..ff917f43 100644 --- a/src/plopp/backends/matplotlib/utils.py +++ b/src/plopp/backends/matplotlib/utils.py @@ -6,7 +6,6 @@ import matplotlib as mpl import matplotlib.pyplot as plt -from matplotlib._pylab_helpers import Gcf from matplotlib.lines import Line2D @@ -63,11 +62,6 @@ def is_widget_backend() -> bool: return any(b in backend for b in ('ipympl', 'nbagg', 'notebook', 'widget')) -def _next_free_figure_num() -> int: - used = Gcf.figs - return 1 if not used else max(used) + 1 - - def make_figure(*args, **kwargs) -> plt.Figure: """ Create a new figure. @@ -82,19 +76,12 @@ def make_figure(*args, **kwargs) -> plt.Figure: ``plt.figure`` returns. To fix this, we need to create a manager for the figure (see https://stackoverflow.com/a/75477367). """ + if not is_interactive_backend(): + return plt.Figure(*args, **kwargs) + if not is_widget_backend(): + return plt.figure(*args, **kwargs) fig = plt.Figure(*args, **kwargs) - if is_interactive_backend(): - # Create a manager for the figure, which makes it interactive, as well as - # making it possible to show the figure from the terminal. - manager = plt._get_backend_mod().new_figure_manager_given_figure( - _next_free_figure_num(), fig - ) - # Register with pyplot global figure manager registry so plt.show() sees it. - # Note that we do not want to do this for interactive jupyter backends as it - # will cause the figure to be automatically displayed in the notebook, - # which we do not want. - if not is_widget_backend(): - Gcf.set_active(manager) + plt._get_backend_mod().new_figure_manager_given_figure(1, fig) return fig From 25169dfa5216231711880e4968ade03db75bc3fc Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Tue, 8 Sep 2026 10:28:36 +0200 Subject: [PATCH 5/5] add comments --- src/plopp/backends/matplotlib/utils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plopp/backends/matplotlib/utils.py b/src/plopp/backends/matplotlib/utils.py index ff917f43..6e7e4117 100644 --- a/src/plopp/backends/matplotlib/utils.py +++ b/src/plopp/backends/matplotlib/utils.py @@ -79,8 +79,12 @@ def make_figure(*args, **kwargs) -> plt.Figure: if not is_interactive_backend(): return plt.Figure(*args, **kwargs) if not is_widget_backend(): + # In this case, we are using an interactive backend outside of a notebook: + # the safest thing to do so that `plt.show()` and `plt.close()` work correctly + # is to use `plt.figure()`. return plt.figure(*args, **kwargs) fig = plt.Figure(*args, **kwargs) + # Create a manager for the figure, which makes it interactive plt._get_backend_mod().new_figure_manager_given_figure(1, fig) return fig