Fix setting artists properties of selectors #20693
Conversation
@larsoner, does this API look good to you? |
Yep, and I tested it and it seems to work for us! |
Great, thanks @larsoner! |
f448e36
to
d73f751
d73f751
to
6a93943
This is ready for review |
I don't think this is a good idea. Having Should we keep them internal (and have public
That depends: How much control do we want to give to the user? |
190c96c
to
9e6394f
Agreed, I have added a
I would lean toward keeping it simple for now! |
def add_artist(self, artist): | ||
"""Add artist to the selector.""" | ||
self._artists.append(artist) | ||
|
||
@property | ||
def artists(self): | ||
"""Tuple of the artists of the selector.""" | ||
return tuple(self._artists) |
ericpre
Jul 28, 2021
Author
Member
I would like to revisit this part in a follow up PR to discuss how to use artists which get updated in a callback, need to drawn at the same time as the selector artists and play well with blitting.
self._direction = direction | ||
self.new_axes(self.ax) | ||
if self._interactive: | ||
self._setup_edge_handle(self._edge_handles._line_props) | ||
line = self._edge_handles.artists[0] | ||
line_props = dict(alpha=line.get_alpha(), |
ericpre
Jul 29, 2021
Author
Member
Is there a way to get the properties relevant to axvline
(the kwargs of axvline
)? line.properties()
returns too many properties.
timhoffm
Jul 30, 2021
Member
Not directly. https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.axvline.html#matplotlib.axes.Axes.axvline says
Valid keyword arguments are Line2D properties, with the exception of 'transform'.
That's because it's a Line2D
, but we enforce the vertical placement using a transform, so this is not user-settable.
ericpre
Aug 5, 2021
Author
Member
Yes, indeed, but there are also other properties (internal properties?), which are not listed in https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.axvline.html#matplotlib.axes.Axes.axvline:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
line = ax.axvline(1.5)
props = line.properties()
del props['transform']
line.set(**props)
Will give the following error:
File "/home/eric/Dev/others/matplotlib/lib/matplotlib/artist.py", line 115, in <lambda>
cls.set = lambda self, **kwargs: Artist.set(self, **kwargs)
File "/home/eric/Dev/others/matplotlib/lib/matplotlib/artist.py", line 1155, in set
return self.update(kwargs)
File "/home/eric/Dev/others/matplotlib/lib/matplotlib/artist.py", line 1060, in update
raise AttributeError(f"{type(self).__name__!r} object "
AttributeError: 'Line2D' object has no property 'children'
Essentially looks good. Since for now, we seem to need the update, |
self._direction = direction | ||
self.new_axes(self.ax) | ||
if self._interactive: | ||
self._setup_edge_handle(self._edge_handles._line_props) | ||
line = self._edge_handles.artists[0] | ||
line_props = dict(alpha=line.get_alpha(), |
timhoffm
Jul 30, 2021
Member
Not directly. https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.axvline.html#matplotlib.axes.Axes.axvline says
Valid keyword arguments are Line2D properties, with the exception of 'transform'.
That's because it's a Line2D
, but we enforce the vertical placement using a transform, so this is not user-settable.
b0545dc
to
73ac533
This is ready for review, I have updated the description of the PR to reflect the current state. |
handle.set(**handle_props) | ||
if self.useblit: | ||
self.update() | ||
self._handle_props.update(handle_props) |
anntzer
Aug 5, 2021
Contributor
You need to normalize properties here (see normalize_kwargs), otherwise with e.g.
from matplotlib.widgets import *
ax = gca()
ss = SpanSelector(ax, print, "horizontal", interactive=True)
ss.set_handle_props(lw=.5); ss.set_handle_props(linewidth=3); ss.direction = "vertical"
the handles' linewidth end up being 0.5, not 3 (also because linewidth
is an explicit kwarg to Line2D whereas lw
is implicitly handled as a generic property, but again I think the correct fix is to just normalize here.)
Likewise for props, probably.
PR Summary
Fix #20618 by adding
set_props
andset_handle_props
method.This PR needs a bit of tidying up but I would like to know if we are happy with this approach!A few others changes:
selector.artists
is now a property returning a tuple of all artists to disallow changing the artists through a public API_selection_artist
and_handles_artists
to access the corresponding artists internally.Remove the use ofSpanSelector._rect
and other, because it is already accessible throughartists[0]
, maybe this is still better to keep a separate attribute?Alternative could be:
props
andhandle_props
setterget_main_artist
get_handle_artists
, which could use asspan.get_main_artist().set(facecolor='green')
, forget_handle_artists
, it would be necessary to loop over the tuplePR Checklist
pytest
passes).flake8
on changed files to check).flake8-docstrings
and runflake8 --docstring-convention=all
).doc/users/next_whats_new/
(follow instructions in README.rst there).doc/api/next_api_changes/
(follow instructions in README.rst there).