Skip to content
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

[Bug]: Cannot Create lines.AxLine #27503

Closed
lprekon opened this issue Dec 12, 2023 · 8 comments · Fixed by #27534
Closed

[Bug]: Cannot Create lines.AxLine #27503

lprekon opened this issue Dec 12, 2023 · 8 comments · Fixed by #27534
Labels
Documentation: API files in lib/ and doc/api
Milestone

Comments

@lprekon
Copy link

lprekon commented Dec 12, 2023

Bug summary

It is impossible to create a new Matplotlib.lines.AxLine artist because the constructor cannot be satisfied

Code for reproduction

import matplotlib.lines as lines

# first attempt
my_first_line = lines.AxLine(xy1=(0, 0), xy2=(1, 1))

# second attempt
my_second_line = lines.AxLine(xy1=(0, 0), slope=1)

#third attempt
my_third_line = lines.AxLine(xy1=(0, 0), xy2=(1, 1), slope=1)

Actual outcome

first attempt:
TypeError: AxLine.__init__() missing 1 required positional argument: 'slope'

second attempt:
TypeError: AxLine.__init__() missing 1 required positional argument: 'xy2'

third attempt:
TypeError: Exactly one of 'xy2' and 'slope' must be given

Expected outcome

The first and second attempt should create and return AxLine objects. Only the third attempt should raise an exception

Additional information

The constructor for AxLine does not provide default values for either 'xy2' or 'slope', which makes both required, resulting in the errors in attempts 1 and 2.

Suggested fix:
default both xy2 and slope to None.

Operating system

No response

Matplotlib Version

3.8.2

Matplotlib Backend

No response

Python version

3.12.1

Jupyter version

No response

Installation

pip

@rcomer
Copy link
Member

rcomer commented Dec 12, 2023

If you want to construct these objects directly, you can explicitly pass None for one of the parameters, e.g.

In [4]: lines.AxLine(xy1=(0, 0), xy2=(1, 1), slope=None)
Out[4]: <matplotlib.lines.AxLine at 0x7fb8639a09d0>

However, the usual way to create these objects is through the axline method which does have the relevant defaults. Do you have a use-case that requires constructing the AxLine directly? Or is there scope to improve our documentation to make it clearer how these things are expected to be handled?

@SarthakNikhal
Copy link

@rcomer Would any changes in lines.AxLine() solve this issue? Let me know if I can work on it if it needs to be done.

@jklymak jklymak added the status: needs clarification Issues that need more information to resolve. label Dec 12, 2023
@lprekon
Copy link
Author

lprekon commented Dec 12, 2023

The idea use case is I'd like to not only draw a line on a chart with AxLine, but I wanted to update it as part of a loop, as part of an animation or a live plot. However, since Axes.AxLine() returns a Line2D object which doesn't support updating slope, I thought I'd create a lines.AxLine artist myself and add it to the axes. If axes.AxLine returned a lines.AxLine instead of a lines.Line2D, that would also work.

So, I can just pass one of the arguments as 'None' and that will work. Maybe axes.AxLine() should also return an AxLine instead of a Line2D?

@jklymak
Copy link
Member

jklymak commented Dec 12, 2023

Axes.axline returns an AxLine object, which has setters for xy1, xy2, and slope. https://matplotlib.org/stable/api/_as_gen/matplotlib.lines.AxLine.html

It does look like the documentation for axes.axline is incorrect about the return type, and that should get fixed.

@jklymak jklymak added Documentation: API files in lib/ and doc/api and removed status: needs clarification Issues that need more information to resolve. labels Dec 12, 2023
@rcomer
Copy link
Member

rcomer commented Dec 12, 2023

@jklymak see #27504 :-)

@jklymak
Copy link
Member

jklymak commented Dec 12, 2023

OK, so we can close this?

@tacaswell
Copy link
Member

We maybe we should also add a note to the __init__ that you must pass both but one must be None?

@timhoffm
Copy link
Member

timhoffm commented Dec 13, 2023

you must pass both but one must be None

This is not the most elegant API. If I would design this now, I‘d make one of the variants a factory class method, but migrating is not worth it and better documentation should be enough.

@rcomer rcomer mentioned this issue Dec 17, 2023
5 tasks
@QuLogic QuLogic added this to the v3.8.3 milestone Dec 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation: API files in lib/ and doc/api
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants