Skip to content

MNT: unify code path of set, update, setp #5599

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 14, 2015

Conversation

tacaswell
Copy link
Member

Single code path for the property -> setter lookup logic.

attn @mdboom

@tacaswell tacaswell added this to the next major release (2.0) milestone Dec 1, 2015
@tacaswell
Copy link
Member Author

A follow on to this might be to implement a priority lookup to sort the key/value pairs instead of alphabetical sorting, but I am not sure if that is replicating functionality already in traitlets.

@WeatherGod
Copy link
Member

I would be +1 on implementing a proper lookup order. The reversed(IIRC)
alphabetical order was a quick-n-dirty solution that I used because it just
so happened that 'edgecolor' > 'color' and such. We won't always be quite
so lucky...

On Tue, Dec 1, 2015 at 11:35 AM, Thomas A Caswell notifications@github.com
wrote:

A follow on to this might be to implement a priority lookup to sort the
key/value pairs instead of alphabetical sorting, but I am not sure if that
is replicating functionality already in traitlets.


Reply to this email directly or view it on GitHub
#5599 (comment)
.


The methods `matplotlib.artist.Artist.set`,
`matplotlib.Artist.update`, and the function `matplotlib.artist.setp`
now use a common codepath to loop up how to update the given artist
Copy link
Member

Choose a reason for hiding this comment

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

loop up how to ? (I think?) The sentence is a little unclear.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed and force-pushed

Single code path for the property -> setter lookup logic.
self.pchanged()
self.stale = True
return ret

def _update_property(self, k, v):
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this could be an embedded function in update(), since it isn't used from anywhere else?

Copy link
Member Author

Choose a reason for hiding this comment

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

good point, when I started I didn't think I would be able to use update everywhere else.

Copy link
Member Author

Choose a reason for hiding this comment

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

on second thought, wouldn't that result in re-defining the function everytime through call to update?

Copy link
Member

Choose a reason for hiding this comment

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

No -- Python will compile the function only once -- it only redefines the local variables each time.

@tacaswell tacaswell force-pushed the mnt_unify_artist_update-set branch from 4f8343b to 63f4437 Compare December 1, 2015 16:48
changed = False
try:
ret = [self._update_property(k, v)
for k, v in sorted(props.items(), reverse=True)]
Copy link
Member

Choose a reason for hiding this comment

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

The sorting by key name is just to prevent any non-deterministic behavior?

Copy link
Member Author

Choose a reason for hiding this comment

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

and makes color/facecolor/edgecolor go in the right order.

Copy link
Member

Choose a reason for hiding this comment

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

Partly. It is also to have a priority structure. If someone defines both
"color" and "facecolor" at the same time, the current behavior is for color
to take precedence over facecolor, IIRC.

On Tue, Dec 1, 2015 at 11:51 AM, Michael Droettboom <
notifications@github.com> wrote:

In lib/matplotlib/artist.py
#5599 (comment):

@@ -845,21 +845,46 @@ def update(self, props):
"""
store = self.eventson
self.eventson = False

  •    changed = False
    
  •    try:
    
  •        ret = [self._update_property(k, v)
    
  •               for k, v in sorted(props.items(), reverse=True)]
    

The sorting by key name is just to prevent any non-deterministic behavior?


Reply to this email directly or view it on GitHub
https://github.com/matplotlib/matplotlib/pull/5599/files#r46304017.

@mdboom
Copy link
Member

mdboom commented Dec 1, 2015

This is cool, and I'm always happy to see PRs that reduce total lines of code ;)

Maybe this is a minor point, but it seems that setp is really the most general of the three, since it can do both an ordered list (in *args) and an unordered dictionary (in **kwargs), so maybe that should be the one that the other two call? That would prevent the need for passing one entry at a time from setp to update.

@tacaswell
Copy link
Member Author

I changed a list to a set literal, this can not be back-ported to 1.5.x.

@WeatherGod
Copy link
Member

Agree with @mdboom. Let setp be the only place where sorting happens. I
haven't looked carefully enough, but I wonder if there are subtle
differences in behavior now.

On Tue, Dec 1, 2015 at 11:55 AM, Michael Droettboom <
notifications@github.com> wrote:

This is cool, and I'm always happy to see PRs that reduce total lines of
code ;)

Maybe this is a minor point, but it seems that setp is really the most
general of the three, since it can do both an ordered list (in _args) and
an unordered dictionary (in *_kwargs), so maybe that should be the one
that the other two call? That would prevent the need for passing one entry
at a time from setp to update.


Reply to this email directly or view it on GitHub
#5599 (comment)
.

Make one call to `update` with the ordered dict rather than
one call per element.
Add the ability to set the precedence of properties when updating
multiple properties on once.

This adds a class-level attribute `Artist._prop_order` which is a
dictionary keyed on property names with integer values.  When using
`set` or `setp` the properties will be applied in descending order by
value then by name.
@mdboom
Copy link
Member

mdboom commented Dec 1, 2015

If we're concerned about subtle changes in behavior, the new zero-tolerance test suite seems to be pretty good at rooting that out. @tacaswell: if you wanted, you could base this on my zero tolerance branch and see if any additional tests are failing beyond the dozen or so that are failing on that branch presently.

@tacaswell
Copy link
Member Author

setp is doing a bunch of extra work. IIRC the ArtistInpsector code is slow (I think the call to kwdoc is one of the more expensive parts of our import time) and we call update many places.

Ended up landing on update -> no sorting, but does the right thing if you pass it an OrderedDict, set -> sorts based on the new _prop_order dict then on key. setp uses both.

properties (either using the setter methods or an attribute/property).

The behavior of `matplotlib.Artist.update` is slightly changed to
returna a list of the returned values from the setter methods to avoid
Copy link
Member

Choose a reason for hiding this comment

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

returna -> return

@tacaswell
Copy link
Member Author

I rebased it locally and have the same 11 failures.

@tacaswell tacaswell force-pushed the mnt_unify_artist_update-set branch from 55370f8 to 1905607 Compare December 1, 2015 20:13
@tacaswell
Copy link
Member Author

Any further thoughts on this? I am tempted to rip the prop_order change back out and give that a more through airing on it's own. I am not 100% sure we will need it with traitlets and I don't want to put it in for 2.0 just to take it out in 2.1.

mdboom added a commit that referenced this pull request Dec 14, 2015
MNT: unify code path of set, update, setp
@mdboom mdboom merged commit 16f4895 into matplotlib:v2.0.x Dec 14, 2015
@tacaswell tacaswell deleted the mnt_unify_artist_update-set branch December 19, 2015 02:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants