Preserve legend settings when regenerating in Qt figure options dialog#31553
Preserve legend settings when regenerating in Qt figure options dialog#31553thesanatt wants to merge 2 commits intomatplotlib:mainfrom
Conversation
When using the Qt figure options dialog to regenerate a legend, previously only ncols and draggable state were preserved. This caused all other legend customizations (loc, fontsize, frameon, shadow, title, mode, spacing, etc.) to be lost. This change extracts and reapplies these properties when regenerating the legend. Closes matplotlib#17775
timhoffm
left a comment
There was a problem hiding this comment.
The issue stems from a larger architectural shortcoming: Legends are not designed to be modified after creation. This makes it necessary to recreate the legend, which results in loosing preexisting properties.
For now, we have to live with this workaround. But the implementation should be different as knowning legend properties is out of scope for the figureoptions dialog: Please create a helper method Legend._get_properties(). So that here you just do
new_legend = axes.legend(ncols=ncols, **old_legend._get_properties())
Please decide whether a white-list of properties or a exclude-list of all legend properties (https://matplotlib.org/stable/api/_as_gen/matplotlib.artist.ArtistInspector.html#matplotlib.artist.ArtistInspector.properties) is more suitable.
The tests are meaningless as they do not exercise the modified code path. Anyway, I would not test options dialog explicitly as that's too cumbersome. Instead think whether you can generate a meaningful non-tautological _get_properties() test. If not we may keep this untested as before.
Address review feedback from @timhoffm: - Added Legend._get_properties() method that returns a dict of legend properties needed for recreation - figureoptions.py now calls old_legend._get_properties() instead of extracting properties inline - Updated tests to directly test _get_properties() method - Tests cover basic properties, mode/bbox_to_anchor, roundtrip recreation, and no-existing-legend edge case
Closes #17775
Summary
When using the Qt figure options dialog and ticking "(Re-)generate automatic legend", previously only
ncolsanddraggablestate were preserved. All other legend customizations (loc, fontsize, frameon, shadow, title, mode, spacing parameters, etc.) were lost.This PR extracts and reapplies these properties from the old legend when regenerating.
Changes
lib/matplotlib/backends/qt_editor/figureoptions.py: Extract legend properties (loc, bbox_to_anchor, fontsize, frameon, shadow, framealpha, title, mode, columnspacing, labelspacing, handlelength, handletextpad) from the existing legend before regenerating, and pass them as kwargs to the newaxes.legend()call.lib/matplotlib/tests/test_figureoptions_legend.py: Added 3 tests covering property preservation, no-existing-legend case, and mode preservation.AI Disclosure
I used AI assistance (Claude) for exploring the codebase and drafting parts of the implementation and tests. All code was reviewed and tested by me.