From 2561bed2659b2c208805e142c54518ff37d63bd2 Mon Sep 17 00:00:00 2001 From: Ritzzer764 Date: Mon, 2 Jun 2025 17:39:24 +0530 Subject: [PATCH 1/3] feat: add ability to toggle legend in the figure options dialog box --- lib/matplotlib/backends/qt_editor/figureoptions.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/matplotlib/backends/qt_editor/figureoptions.py b/lib/matplotlib/backends/qt_editor/figureoptions.py index 9d31fa9ced2c..0be694b6beea 100644 --- a/lib/matplotlib/backends/qt_editor/figureoptions.py +++ b/lib/matplotlib/backends/qt_editor/figureoptions.py @@ -61,6 +61,7 @@ def convert_limits(lim, converter): ) for name, axis in axis_map.items() ]), + ('Legend visible', axes.legend_ is not None), ('(Re-)Generate automatic legend', False), ] @@ -196,6 +197,7 @@ def apply_callback(data): title = general.pop(0) axes.set_title(title) generate_legend = general.pop() + legend_visible = general.pop() for i, (name, axis) in enumerate(axis_map.items()): axis_min = general[4*i] @@ -256,6 +258,10 @@ def apply_callback(data): if new_legend: new_legend.set_draggable(draggable) + # toggle legend visibility + if axes.legend_ is not None: + axes.legend_.set_visible(legend_visible) + # Redraw figure = axes.get_figure() figure.canvas.draw() From 1a8a6dbad5b6ceae745f964a104b4d10b1bde1a6 Mon Sep 17 00:00:00 2001 From: Ritzzer764 Date: Tue, 1 Jul 2025 17:50:00 +0530 Subject: [PATCH 2/3] test: add test case to toggle legend visibility --- lib/matplotlib/tests/test_backend_qt.py | 41 +++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/lib/matplotlib/tests/test_backend_qt.py b/lib/matplotlib/tests/test_backend_qt.py index 60f8a4f49bb8..bba07371f6f8 100644 --- a/lib/matplotlib/tests/test_backend_qt.py +++ b/lib/matplotlib/tests/test_backend_qt.py @@ -251,6 +251,47 @@ def test_figureoptions_with_datetime_axes(): with mock.patch("matplotlib.backends.qt_compat._exec", lambda obj: None): fig.canvas.manager.toolbar.edit_parameters() +@pytest.mark.backend('QtAgg', skip_on_importerror=True) +@pytest.mark.parametrize("legend_visible", [True, False]) +def test_legend_checkbox_toggle(legend_visible): + fig, ax = plt.subplots() + ax.plot([1, 2, 3], label='Line 1') + ax.legend() + ax.legend_.set_visible(not legend_visible) # Set initial visibility opposite to the test case + + with mock.patch.object(fig.canvas, 'draw') as mock_draw, \ + mock.patch.object(fig.canvas, 'toolbar', create=True): + callback = None + def fake_fedit(datalist, title, parent=None, icon=None, apply=None): + nonlocal callback + callback = apply + return datalist + + with mock.patch.object(matplotlib.backends.qt_editor.figureoptions._formlayout, 'fedit', side_effect=fake_fedit): + matplotlib.backends.qt_editor.figureoptions.figure_edit(ax) + + xlim = ax.get_xlim() + ylim = ax.get_ylim() + xlabel = ax.get_xlabel() + ylabel = ax.get_ylabel() + xscale = ax.get_xscale() + yscale = ax.get_yscale() + + form_data = [ + [ + "Title", + xlim[0], xlim[1], xlabel, xscale, + ylim[0], ylim[1], ylabel, yscale, + legend_visible, + False + ], + [ + ['Title', '-', 'default', 1.5, '#1f77b4ff', '', 6.0, '#1f77b4ff', '#1f77b4ff'] + ] + ] + + callback(form_data) + assert ax.legend_.get_visible() == legend_visible @pytest.mark.backend('QtAgg', skip_on_importerror=True) def test_double_resize(): From 60ba458be802c207e720228f51006f090fc64837 Mon Sep 17 00:00:00 2001 From: Ritzzer764 Date: Tue, 1 Jul 2025 17:55:59 +0530 Subject: [PATCH 3/3] style: format ruff --- lib/matplotlib/tests/test_backend_qt.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/tests/test_backend_qt.py b/lib/matplotlib/tests/test_backend_qt.py index bba07371f6f8..c63d5f4bb4fe 100644 --- a/lib/matplotlib/tests/test_backend_qt.py +++ b/lib/matplotlib/tests/test_backend_qt.py @@ -251,13 +251,15 @@ def test_figureoptions_with_datetime_axes(): with mock.patch("matplotlib.backends.qt_compat._exec", lambda obj: None): fig.canvas.manager.toolbar.edit_parameters() + @pytest.mark.backend('QtAgg', skip_on_importerror=True) @pytest.mark.parametrize("legend_visible", [True, False]) def test_legend_checkbox_toggle(legend_visible): fig, ax = plt.subplots() ax.plot([1, 2, 3], label='Line 1') - ax.legend() - ax.legend_.set_visible(not legend_visible) # Set initial visibility opposite to the test case + ax.legend() + ax.legend_.set_visible(not legend_visible) + # Set initial visibility opposite to the test case with mock.patch.object(fig.canvas, 'draw') as mock_draw, \ mock.patch.object(fig.canvas, 'toolbar', create=True): @@ -267,7 +269,8 @@ def fake_fedit(datalist, title, parent=None, icon=None, apply=None): callback = apply return datalist - with mock.patch.object(matplotlib.backends.qt_editor.figureoptions._formlayout, 'fedit', side_effect=fake_fedit): + with mock.patch.object(matplotlib.backends.qt_editor.figureoptions._formlayout, + 'fedit', side_effect=fake_fedit): matplotlib.backends.qt_editor.figureoptions.figure_edit(ax) xlim = ax.get_xlim() @@ -283,16 +286,18 @@ def fake_fedit(datalist, title, parent=None, icon=None, apply=None): xlim[0], xlim[1], xlabel, xscale, ylim[0], ylim[1], ylabel, yscale, legend_visible, - False + False ], [ - ['Title', '-', 'default', 1.5, '#1f77b4ff', '', 6.0, '#1f77b4ff', '#1f77b4ff'] + ['Title', '-', 'default', 1.5, '#1f77b4ff', '', + 6.0, '#1f77b4ff', '#1f77b4ff'] ] - ] + ] callback(form_data) assert ax.legend_.get_visible() == legend_visible + @pytest.mark.backend('QtAgg', skip_on_importerror=True) def test_double_resize(): # Check that resizing a figure twice keeps the same window size