Skip to content

[WIP] Add Axes method for drawing infinite lines. #7506

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

Closed
wants to merge 1 commit into from

Conversation

QuLogic
Copy link
Member

@QuLogic QuLogic commented Nov 24, 2016

This is an implementation of an infinite line artist following the transforms I outlined in #5253. However, I did need to change from ax.dataLim to ax.viewLim because the former is infinite when nothing else is on the plot. I'm not sure if that will cause problems (maybe in log-scaled plots?), though it seems to work:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.axline(linewidth=4, color='r')
ax.axline(intercept=1)
ax.axline(slope=5)
ax.grid(True)
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
plt.show()

figure_1 https://youtu.be/DJjbFMoAw68

Unlike axhline and axvline, there is no [xy]{min,max} or autoscaling based on these artists because I don't think it makes sense for infinite lines.

I've only implemented slope/intercept and not any of the alternates in #5253; not sure which ones we want to support. Also needs some tests, wrapper in pyplot, etc., so it's still WIP.

@QuLogic QuLogic added this to the 2.1 (next point release) milestone Nov 24, 2016
@QuLogic
Copy link
Member Author

QuLogic commented Nov 24, 2016

On a semilog plot, this is not correct, which can be seen by doing some interpolation:
figure_1-1
The red line is not interpolated at all and is completely wrong; the dashed blue line is how ax.plot works, which also uses no interpolation but keeps the right endpoints only; the green line is how axline would work with a bit of extra points (instead of just 0,0->1,1). As can be seen in the figure, this requires a bit of finesse with the sampling as moving the view around will change the smoothness of the curve depending on how close it is to the asymptotes.

I guess it might be possible to tweak the sampling to get this right, though I don't want to spend too much time trying until we're sure what the intended API/effect is here.

loglog plots look okay since lines are still lines on them.

@dstansby
Copy link
Member

This is pretty neat! Given plot is technically broken on semi-log plots (as shown above), I think adding the current axline version that works on log-log and linear-linear would be fine.

Copy link
Member

@dstansby dstansby left a comment

Choose a reason for hiding this comment

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

This also needs a what's new entry, at least an image test, and some edge case tests too. (slope zero, negative slope, very large slope are the ones that come to my mind right now). Otherwise looks good!

@@ -794,6 +794,69 @@ def axvline(self, x=0, ymin=0, ymax=1, **kwargs):
return l

@docstring.dedent_interpd
def axline(self, slope=1, intercept=0, **kwargs):
"""
Add an infinite line across the axes.
Copy link
Member

Choose a reason for hiding this comment

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

'across an axis'?


Parameters
----------
slope : scalar, optional, default: 1
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason this and intercept are optional? I would say the user should be forced to give them.

See Also
--------
axhline : for strictly horizontal lines
axvline : for strictly vertical lines
Copy link
Member

Choose a reason for hiding this comment

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

Do these get automatically linked? If not would be nice to have some sphinx markup to link to relevant methods.

@syrte
Copy link

syrte commented Apr 21, 2017

A tentative suggestion on arguments, how about following forms:

def axline(a, b, *args, **kwargs):
    """
    a, b: scalar or tuple
        Acceptable forms are
        y0, b:
            y = y0 + b * x
        (x0, y0), b:
            y = y0 + b * (x - x0)
        (x0, y0), (x1, y1):
            y = y0 + (y1 - y0) / (x1 - x0) * (x - x0)
    ...

Accept following combinations:

  • intercept, slope
  • point, slope
  • point, point

This may cover most forms as suggeted by #5253 .

Surely, we may assign default value to a, b as you do.

@dstansby
Copy link
Member

@QuLogic do you have any plans to work on this? If not let me know and I'm happy to pick it up. I think it would be a cool and useful feature to add.

@QuLogic
Copy link
Member Author

QuLogic commented Aug 26, 2017

I don't really have time at the moment, so feel free to prepare something based on it.

@dstansby dstansby modified the milestones: 2.2 (next next feature release), 2.1 (next point release) Aug 26, 2017
@dstansby dstansby self-assigned this Oct 8, 2017
@dstansby
Copy link
Member

Closing in favour of #9321

@dstansby dstansby closed this Jan 10, 2018
@dstansby dstansby removed their assignment Jan 10, 2018
@QuLogic QuLogic modified the milestones: needs sorting, v2.2.0 Feb 13, 2018
@QuLogic QuLogic modified the milestones: v2.2.0, v3.3.0 Nov 22, 2019
@QuLogic QuLogic deleted the abline branch April 16, 2021 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants