Fix containment test with nonlinear transforms.#7844
Fix containment test with nonlinear transforms.#7844dstansby merged 2 commits intomatplotlib:masterfrom
Conversation
Current coverage is 62.10% (diff: 60.00%)@@ master #7844 diff @@
==========================================
Files 174 174
Lines 56051 56054 +3
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
+ Hits 34808 34811 +3
Misses 21243 21243
Partials 0 0
|
|
Can you add a regression test? |
|
Done. |
lib/matplotlib/path.py
Outdated
| result = _path.point_in_path(point[0], point[1], radius, self, | ||
| transform) | ||
| return result | ||
| from .transforms import Affine2D |
There was a problem hiding this comment.
Any reason to have this here and not at the top of the module as python convention require?
There was a problem hiding this comment.
Probably dates back to when I implemented this as a quickfix. Moved up.
652371f to
ac133e8
Compare
ac133e8 to
7d67293
Compare
|
Actually there is a circular import between transforms.py and path.py, so I left the Affine2D import inside the function, with a note to that effect. |
|
Test failure is probably related to pytest migration... we can wait until it is done, as that seems close(?). |
|
Let's wait until the pytest migration is over. But, can we fix the circular import in a more robust way? |
|
This would likely imply a small performance cost as |
|
I would feel much more comfortable with fixing the circular import. |
|
There's also and would have to become something like which is worse than a circular import IMO. |
I don't think this should be merge with a circular import.
|
What is you preferred solution other than the circular import, then? As mentioned above I can work around it by obfuscating the implementation of |
lib/matplotlib/path.py
Outdated
| # We need to import Affine2D here to prevent a circular import between | ||
| # the .path and .transforms modules. | ||
| from .transforms import Affine2D | ||
| if transform and not isinstance(transform, Affine2D): |
There was a problem hiding this comment.
Can't this be if not transform.is_affine: ? That seems way better that isinstance anyway.
7d67293 to
ffd60aa
Compare
| polygon = ax.axvspan(1, 10) | ||
| assert polygon.get_path().contains_point( | ||
| ax.transData.transform_point((5, .5)), ax.transData) | ||
|
|
There was a problem hiding this comment.
May also be worth checking that the points (0.5, 0.5) and (20, 0.5) are not inside polygon
| # transform the path ourselves. If `transform` is affine, letting | ||
| # `point_in_path` handle the transform avoids allocating an extra | ||
| # buffer. | ||
| if transform and not transform.is_affine: |
There was a problem hiding this comment.
Is there a reason not to just do the transformation here even if it is an affine transformation? (thus removing the if block)
There was a problem hiding this comment.
I guess you may save the creation of a large temporary (if the c++ code does the transform one point at a time), which would be relevant for very large paths.
To be honest I don't know but decided not to take any risks.
ffd60aa to
76173e1
Compare
dstansby
left a comment
There was a problem hiding this comment.
👍 Will merge if/when tests pass
Fixes #3540; see in particular #3540 (comment).
Edit: Also fixes #7655.
@mdboom Would it be reasonable to remove the definition of
Transform.__array__and only keepAffine2D.__array__, thus forcing call sites to explicitly only pass in affine transforms to the C++ code, rather than sometimes silently dropping the nonlinear part (as in this case)?