Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Preserve legend settings when regenerating in Qt figure options dialog#31553

Open
thesanatt wants to merge 2 commits intomatplotlib:mainfrom
thesanatt:fix/legend-settings-qt
Open

Preserve legend settings when regenerating in Qt figure options dialog#31553
thesanatt wants to merge 2 commits intomatplotlib:mainfrom
thesanatt:fix/legend-settings-qt

Conversation

@thesanatt
Copy link
Copy Markdown

Closes #17775

Summary

When using the Qt figure options dialog and ticking "(Re-)generate automatic legend", previously only ncols and draggable state 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 new axes.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.

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
Copy link
Copy Markdown
Member

@timhoffm timhoffm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

clone more legend settings when regenerating in Qt figure options dialog

2 participants