From edf807667a60118a6fb3e31c4ea276c8e2826fce Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Fri, 31 Jan 2025 07:53:01 -0500 Subject: [PATCH] Backport PR #29546: FIX: pyplot.matshow figure handling --- lib/matplotlib/pyplot.py | 18 +++++++++++------- lib/matplotlib/tests/test_pyplot.py | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 12aedf5157ca..48aea1b3bd9c 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -994,8 +994,8 @@ def figure( root_fig = num.get_figure(root=True) if root_fig.canvas.manager is None: raise ValueError("The passed figure is not managed by pyplot") - elif any([figsize, dpi, facecolor, edgecolor, not frameon, - kwargs]) and root_fig.canvas.manager.num in allnums: + elif (any(param is not None for param in [figsize, dpi, facecolor, edgecolor]) + or not frameon or kwargs) and root_fig.canvas.manager.num in allnums: _api.warn_external( "Ignoring specified arguments in this call because figure " f"with num: {root_fig.canvas.manager.num} already exists") @@ -1007,8 +1007,8 @@ def figure( if num is None: num = next_num else: - if any([figsize, dpi, facecolor, edgecolor, not frameon, - kwargs]) and num in allnums: + if (any(param is not None for param in [figsize, dpi, facecolor, edgecolor]) + or not frameon or kwargs) and num in allnums: _api.warn_external( "Ignoring specified arguments in this call " f"because figure with num: {num} already exists") @@ -2662,9 +2662,13 @@ def matshow(A: ArrayLike, fignum: None | int = None, **kwargs) -> AxesImage: if fignum == 0: ax = gca() else: - # Extract actual aspect ratio of array and make appropriately sized - # figure. - fig = figure(fignum, figsize=figaspect(A)) + if fignum is not None and fignum_exists(fignum): + # Do not try to set a figure size. + figsize = None + else: + # Extract actual aspect ratio of array and make appropriately sized figure. + figsize = figaspect(A) + fig = figure(fignum, figsize=figsize) ax = fig.add_axes((0.15, 0.09, 0.775, 0.775)) im = ax.matshow(A, **kwargs) sci(im) diff --git a/lib/matplotlib/tests/test_pyplot.py b/lib/matplotlib/tests/test_pyplot.py index 21036e177045..1aaa8dd93ca2 100644 --- a/lib/matplotlib/tests/test_pyplot.py +++ b/lib/matplotlib/tests/test_pyplot.py @@ -459,13 +459,13 @@ def test_figure_hook(): def test_multiple_same_figure_calls(): - fig = mpl.pyplot.figure(1, figsize=(1, 2)) + fig = plt.figure(1, figsize=(1, 2)) with pytest.warns(UserWarning, match="Ignoring specified arguments in this call"): - fig2 = mpl.pyplot.figure(1, figsize=(3, 4)) + fig2 = plt.figure(1, figsize=np.array([3, 4])) with pytest.warns(UserWarning, match="Ignoring specified arguments in this call"): - mpl.pyplot.figure(fig, figsize=(5, 6)) + plt.figure(fig, figsize=np.array([5, 6])) assert fig is fig2 - fig3 = mpl.pyplot.figure(1) # Checks for false warnings + fig3 = plt.figure(1) # Checks for false warnings assert fig is fig3 @@ -475,3 +475,11 @@ def test_close_all_warning(): # 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") + + +def test_matshow(): + fig = plt.figure() + arr = [[0, 1], [1, 2]] + + # Smoke test that matshow does not ask for a new figsize on the existing figure + plt.matshow(arr, fignum=fig.number)