-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ENH: rely on non-rectangular patch paths rather than bboxes for legend auto-placing (fix #9580) #9598
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
Conversation
e97e93c
to
414d4f8
Compare
Sorry, I let an F-string from former iterations in the previous commit (3.6+ ❤️)... I fixed it and rebased to squash the one character-commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to add a "the auto-legend locator algorithm has been tweaked" note in the API changes, without necessarily going into the details (so if we change it again before the next release it would be OK to leave it as it is), mostly to leave a breadcrumb if anyone is confused by the change in behavior.
I honestly wouldn't worry about the loss of a clearly less optimal behavior.
So with this change it could place a legend inside a non-solid bar (if the bar is big enough)? |
good point... (but I think being fully in a solid polygon is less annoying that crossing some boundaries) |
You could check if the legend was inside any polygons as well though your second test would fail. But I don’t think most of the time you want the legend inside a drawn polygon. |
How much computation time does this add? With the 'auto' behavior now the default this is a bit of a hot-path for people updating plots. |
@anntzer: I added an entry in @tacaswell: I tried to write a benchmark script here. It seems to me that the performance impact is barely noticeable (between +0.9% and +1.3% of execution time in the examples of the benchmark). However TBH I know very little about profiling (and monkey-patching with The plots used for benchmarking look like: and they are more intended to give hard time to the One can see that the behavior with the patch collection is still quite surprising (not to say wrong...), and there is something weird with the plot coordinates. (I guess that I missed some @Kojoley and @jklymak: I am still looking into the consequences of this PR in the kind of situations that you suggested! Edit: Added some values from the benchmark results. |
Putting back the [WiP] mark, as some legitimate questions about the consequences of this PR have been made and still need to be evaluated. |
Personally, I think putting a legend inside an artist is an OK fallback, but only if it can't be put outside an artist. I wonder if a "better" way to go would be doing the old bounding box check first and then, only if that fails for all possible locations, do the intersecting-vertex check. I think that gets better behaviour but still preserves the spirit of this PR. |
Also, looking at the above, I wonder if the check order needs to be changed. I'd far prefer the legend top center than bottom center in the first test. |
@jklymak About the check order: I was having the same thought (but usually @tacaswell is a bit reluctant with API changes just for “aesthetic” reasons 😈 :P). Anyway, other things are broken/weird with the check order, for example "(centered) right" seems to be evaluated twice but not even in successive positions... For your other idea, that is an interesting idea, I'll try to give it a shot when I have more time (likely not today...). |
ping @afvincent I still think this is a great enhancement.... |
@jklymak I did not forget it ;). It is simply that day-job and other more natural events (Thomas Fire, I am speaking of you 😈) have required a significant share of my attention during the past few weeks... Hopefully I will have more time to take care of this (and the other PRs I opened recently) during the second half of December. If something is really urgent, I do not mind friendly take overs. But I guess that the next “deadline” was pushed to 2.2, which gives a bit of time, does it not? |
Yeah, but 2.2 has over 900 issues, so we will be busy ;-) |
ping @afvincent real-life bah! I still think this should go in, maybe after some mods... |
@jklymak Hearing you loud and clear, and this PR is still in my on-going work list ;). I am still trying to find a useful way to benchmark that change (IIRC @tacaswell was a bit worry about that change). Besides, there was also a comment in the thread about the fact that the default order used to explore the possible position might not be the most “intuitive” one (whatever this means :P), but I guess that we might re-evaluate it for 3.0 if that is relevant. |
As someone who is slowing down drawing as fast as others are speeding it up, I disagree that perfomance is a huge issue (within reason). If a user needs performance, they shouldn't use automatic convenience functions, i.e in this case, they can specify the location kwarg. But thats just my vote; I appreciate that its also the default, so it has the potential to slow people down by default is an issue. My only problem w/ this PR is that I think its possible to theoretically put the legend inside the data curve, and that doesn't appeal. At the very least, this could get its own value for the location kwarg. "superauto"? |
Would rather not introduce a new location keyword, keep things lean, yada yada. If it's just a 1% slowdown I wouldn't worry to much about it... |
ping @afvincent - I think this one was quite close if you have time... |
Annual ping @afvincent... |
3e5f556
to
5f5c798
Compare
I took the liberty of rebasing this and think it is ready for re-review. |
5f5c798
to
694e2f4
Compare
@jklymak Can you please make the call if this should go in or be pushed to 3.8? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it should work and not be too much of a speed drain (beyond what best already does). Thanks for rebasing @tacaswell.
I took the liberty of doing a squash merge |
…d auto-placing (fix matplotlib#9580) (matplotlib#9598) * use path rather than bbox for non rectangular patches * Add tests * Add a short breadcrumb note in api_changes
It took 5 years to merge this PR 🙂 |
PR Summary
This PR addresses issue #9580.
Rationale
Currently, when using the legend auto-placing (NB: default since 2.0), one can get significantly surprising results as

where things are OK with the two upper subplots but the two lower ones are not.
As @anntzer explained in #9580, this is because "step*" histogram types return a single
Polygon
patch while non-"step*" types return a list ofRectangle
patches. As the legend auto-placing algorithm relies on the bbox of the patches, it can significantly overestimates the actual patch area (e.g. as in the case displayed above). This PR simply suggests to use the path that defines non-rectangular patches instead of their bbox in the legend auto-placing algorithm. By doing this the algorithm should handle these patches as well (or bad) as any Line2D instances.At least, it fixes the previous example...

Remaining concerns
NB: the followings points are kind of related actually.
Is it not kind of a nuke to treat every non-rectangular patches as a path?
A less radical change may be to keep the current bbox-based approach for some other patches like
Ellipse
,Circle
, etc. where the issue stated above is less “severe” and the bbox provide a quite good approximation of the area that is covered by the patch.What about speed?
A very crude and genuine benchmark with a ~ 1000 bin-histogram is given in #9580 and suggest than this change is not likely to be the performance bottleneck of legend. If I am correct, at least for histograms, the new approach should not be really more computationally expensive than the cost of the non-step* histogram types, where the legend bbox is tested against every
Rectangle
patch the histogram is made of, isn't it? However, it may be worth to check that performance does not become a issue for plot with very high amounts of “complex” patches.PR Checklist
This breaks the previously “incorrect” behavior, and there will be no way to recover it. @tacaswell Should I add a proper entry in
api_changes.rst
about it?