diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 3b1a01c28408..52850f128cae 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -983,30 +983,42 @@ def figure( `~matplotlib.rcParams` defines the default values, which can be modified in the matplotlibrc file. """ + allnums = get_fignums() + if isinstance(num, FigureBase): # type narrowed to `Figure | SubFigure` by combination of input and isinstance if num.canvas.manager is None: raise ValueError("The passed figure is not managed by pyplot") + elif any([figsize, dpi, facecolor, edgecolor, not frameon, + kwargs]) and num.canvas.manager.num in allnums: + _api.warn_external( + "Ignoring specified arguments in this call " + f"because figure with num: {num.canvas.manager.num} already exists") _pylab_helpers.Gcf.set_active(num.canvas.manager) return num.figure - allnums = get_fignums() next_num = max(allnums) + 1 if allnums else 1 fig_label = '' if num is None: num = next_num - elif isinstance(num, str): - fig_label = num - all_labels = get_figlabels() - if fig_label not in all_labels: - if fig_label == 'all': - _api.warn_external("close('all') closes all existing figures.") - num = next_num - else: - inum = all_labels.index(fig_label) - num = allnums[inum] else: - num = int(num) # crude validation of num argument + if any([figsize, dpi, facecolor, edgecolor, not frameon, + kwargs]) and num in allnums: + _api.warn_external( + "Ignoring specified arguments in this call " + f"because figure with num: {num} already exists") + if isinstance(num, str): + fig_label = num + all_labels = get_figlabels() + if fig_label not in all_labels: + if fig_label == 'all': + _api.warn_external("close('all') closes all existing figures.") + num = next_num + else: + inum = all_labels.index(fig_label) + num = allnums[inum] + else: + num = int(num) # crude validation of num argument # Type of "num" has narrowed to int, but mypy can't quite see it manager = _pylab_helpers.Gcf.get_fig_manager(num) # type: ignore[arg-type] diff --git a/lib/matplotlib/tests/test_pyplot.py b/lib/matplotlib/tests/test_pyplot.py index a077aede8f8b..63dc239df2e8 100644 --- a/lib/matplotlib/tests/test_pyplot.py +++ b/lib/matplotlib/tests/test_pyplot.py @@ -457,3 +457,22 @@ def test_figure_hook(): fig = plt.figure() assert fig._test_was_here + + +def test_multiple_same_figure_calls(): + fig = mpl.pyplot.figure(1, figsize=(1, 2)) + with pytest.warns(UserWarning, match="Ignoring specified arguments in this call"): + fig2 = mpl.pyplot.figure(1, figsize=(3, 4)) + with pytest.warns(UserWarning, match="Ignoring specified arguments in this call"): + mpl.pyplot.figure(fig, figsize=(5, 6)) + assert fig is fig2 + fig3 = mpl.pyplot.figure(1) # Checks for false warnings + assert fig is fig3 + + +def test_close_all_warning(): + fig1 = plt.figure() + + # Check that the warning is issued when 'all' is passed to plt.figure + with pytest.warns(UserWarning, match="closes all existing figures"): + fig2 = plt.figure("all")