Skip to content

Commit f3359a3

Browse files
authored
Add warning for multiple pyplot.figure calls with same ID (#27992)
1 parent 55cf8c7 commit f3359a3

File tree

2 files changed

+43
-12
lines changed

2 files changed

+43
-12
lines changed

lib/matplotlib/pyplot.py

+24-12
Original file line numberDiff line numberDiff line change
@@ -983,30 +983,42 @@ def figure(
983983
`~matplotlib.rcParams` defines the default values, which can be modified
984984
in the matplotlibrc file.
985985
"""
986+
allnums = get_fignums()
987+
986988
if isinstance(num, FigureBase):
987989
# type narrowed to `Figure | SubFigure` by combination of input and isinstance
988990
if num.canvas.manager is None:
989991
raise ValueError("The passed figure is not managed by pyplot")
992+
elif any([figsize, dpi, facecolor, edgecolor, not frameon,
993+
kwargs]) and num.canvas.manager.num in allnums:
994+
_api.warn_external(
995+
"Ignoring specified arguments in this call "
996+
f"because figure with num: {num.canvas.manager.num} already exists")
990997
_pylab_helpers.Gcf.set_active(num.canvas.manager)
991998
return num.figure
992999

993-
allnums = get_fignums()
9941000
next_num = max(allnums) + 1 if allnums else 1
9951001
fig_label = ''
9961002
if num is None:
9971003
num = next_num
998-
elif isinstance(num, str):
999-
fig_label = num
1000-
all_labels = get_figlabels()
1001-
if fig_label not in all_labels:
1002-
if fig_label == 'all':
1003-
_api.warn_external("close('all') closes all existing figures.")
1004-
num = next_num
1005-
else:
1006-
inum = all_labels.index(fig_label)
1007-
num = allnums[inum]
10081004
else:
1009-
num = int(num) # crude validation of num argument
1005+
if any([figsize, dpi, facecolor, edgecolor, not frameon,
1006+
kwargs]) and num in allnums:
1007+
_api.warn_external(
1008+
"Ignoring specified arguments in this call "
1009+
f"because figure with num: {num} already exists")
1010+
if isinstance(num, str):
1011+
fig_label = num
1012+
all_labels = get_figlabels()
1013+
if fig_label not in all_labels:
1014+
if fig_label == 'all':
1015+
_api.warn_external("close('all') closes all existing figures.")
1016+
num = next_num
1017+
else:
1018+
inum = all_labels.index(fig_label)
1019+
num = allnums[inum]
1020+
else:
1021+
num = int(num) # crude validation of num argument
10101022

10111023
# Type of "num" has narrowed to int, but mypy can't quite see it
10121024
manager = _pylab_helpers.Gcf.get_fig_manager(num) # type: ignore[arg-type]

lib/matplotlib/tests/test_pyplot.py

+19
Original file line numberDiff line numberDiff line change
@@ -457,3 +457,22 @@ def test_figure_hook():
457457
fig = plt.figure()
458458

459459
assert fig._test_was_here
460+
461+
462+
def test_multiple_same_figure_calls():
463+
fig = mpl.pyplot.figure(1, figsize=(1, 2))
464+
with pytest.warns(UserWarning, match="Ignoring specified arguments in this call"):
465+
fig2 = mpl.pyplot.figure(1, figsize=(3, 4))
466+
with pytest.warns(UserWarning, match="Ignoring specified arguments in this call"):
467+
mpl.pyplot.figure(fig, figsize=(5, 6))
468+
assert fig is fig2
469+
fig3 = mpl.pyplot.figure(1) # Checks for false warnings
470+
assert fig is fig3
471+
472+
473+
def test_close_all_warning():
474+
fig1 = plt.figure()
475+
476+
# Check that the warning is issued when 'all' is passed to plt.figure
477+
with pytest.warns(UserWarning, match="closes all existing figures"):
478+
fig2 = plt.figure("all")

0 commit comments

Comments
 (0)