-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Axes.axline: implement support transform argument (for points but not slope) #18647
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
for plotting a line through a point in axes coordinates and with a slope in data coordinates fixes matplotlib#18625
When we originally put in axline, we had a big back and forth about how to specify the line, and it was decided that two points were just as good as point/slope. So I'm not sure this feature is particularly needed, though its actually how I would have preferred specifying the line. |
Point and slope is already available in axline. This is specifically about specifying the point in axes coordinates instead of data coordinates, so that the line stays at the same position when moving the viewport. |
oops, sorry, I see... |
lib/matplotlib/tests/test_axes.py
Outdated
@@ -4072,6 +4072,19 @@ def test_axline(fig_test, fig_ref): | |||
ax.axvline(-0.5, color='C5') | |||
|
|||
|
|||
@check_figures_equal() | |||
def test_axline_transform(fig_test, fig_ref): |
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 useful to add a test where you call the method, and then subsequently resize the figure (simulating a manual resize) and show this still yields the expected line. Also that its robust to panning and zooming.
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.
Sure. I added some an additional test in 45e5bc7 which uses set_xlim
/set_ylim
and set_size_inches
to simulate resize and pan/zoom, is that what you meant?
lib/matplotlib/lines.py
Outdated
def get_transform(self): | ||
ax = self.axes | ||
(vxlo, vylo), (vxhi, vyhi) = ax.transScale.transform(ax.viewLim) | ||
x, y = (ax.transAxes + ax.transData.inverted()).transform(self._xy1) |
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.
Wouldn't it be simpler to calculate the slope into axes coordinates and simply draw the line in axes co-ordinates?
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.
Good idea. I tried to stay close to the implementation of axline
(as the original idea was to add this behavior into that function if a transform is passed, see #18625), but this may be an easier option.
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.
Hm, but it won't really get much simpler because we still need to somehow convert to data coordinates to calculate at which edges of the viewport (top/bottom or left/right) the ends of the line would be. That will of course depend on the current x/y limits.
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.
Wont the line clip if you just make it go from x_axes = -1 to 2?
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.
Ah, right, it does. I implemented a simpler solution in da040d0, however it breaks the tests even though the plots visually seem to look the same. The difference seems to be very small, not sure why this is happening 😕
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.
You could probably safely up the tolerance if this is just roundoff from passing the positions through the transform stack...
@check_figures_equal(extensions=['png'], tol=0.19)
Overall this seems good, and I guess I agree that we can't just make this an example. I'm not at all sure about the name chosen? Be sure to ping us for reviews if this starts slipping down the PR list. Things get forgotten.... |
Yeah, I'm not sure either. Some other ideas: |
From the peanut gallery, I would rather add a special case in the codepath of |
I'd like to see use-cases to guide us in the naming and exact functionality. Proposed so far:
I currently don't see any others: The slope is in data space, but the positions are in Axes coordinates, so the positions are data-independent; i.e. the lines only describe "a data direction" (maybe that's already a hint for a name). If it's just a direction without position, would we not anyway want a grid to indicate the direction homogeneously across all positions? If so, we might want to instead make a function that directly creates the grid (e.g. |
I agree with the above, though I somewhat cringe at the idea of a grid API versus just a single line. Specifying a sloping grid in axes co-ordinates in a general way is not trivial. I also agree that maybe this should be handled by |
I'll add this one to the agenda of the weekly call since the API choices seem complicated. |
@johan12345 We discussed this on the weekly developer call. The consensus was that this can and should be handled with the Hopefully that is not too annoying, as you have gone a ways down this path, but the consensus was that adding a transform was the easiest API... |
Ooops sorry I see Tim commented on the original issue. Sorry for the noise. |
@jklymak Thanks! Yes, as written in the original issue #18625 I have now tried to adapt One thing that is not implemented for the case where a transformation is passed is the adjustment of data limits:
What do you think? |
I mean if the line is in Axes space (but with a data slope) I don't think the intention is for it to be treated as data so the limits should not change? But I don't 100% understand the use of the feature.... |
Co-authored-by: Tim Hoffmann <[email protected]>
Co-authored-by: Tim Hoffmann <[email protected]>
Thanks @timhoffm! |
(already done by super.__init__())
So code coverage is complaining, and though it's pointing to a weird place, it is correctly finding a bug: the However, this turns out to work, since So perhaps that check is unnecessary and handling |
Well, that is probably what changed when I removed the explicit setting of self._transform... Okay, I can remove that as well. |
No, as I said, it checks |
Thanks @johan12345! Congratulations on your first PR to Matplotlib 🎉 We hope to hear from you again. |
PR Summary
for plotting a line through a point in axes coordinates and with a slope in data coordinates
see #18625 for details and example.
PR Checklist
pytest
passes).flake8
on changed files to check).flake8-docstrings
andpydocstyle<4
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).