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

Only modify axes once plot is ran #30

Open
tjstienstra opened this issue Oct 12, 2024 · 0 comments
Open

Only modify axes once plot is ran #30

tjstienstra opened this issue Oct 12, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@tjstienstra
Copy link
Owner

Describe the bug
If you forget to run symmeplot.matplotlib.scene.Scene3D.plot, you can get a rather weird error because artists have not been added to the axes yet. This specifically occurs when you have attached a circle to a body.

To Reproduce
Steps to reproduce the behavior:

  1. Run the following code.
    from symmeplot.matplotlib import Scene3D
    import sympy.physics.mechanics as me
    import matplotlib.pyplot as plt
    
    scene = Scene3D(me.ReferenceFrame("N"), me.Point("N_0"))
    b = scene.add_body(me.RigidBody("N", scene.zero_point, scene.inertial_frame))
    b.attach_circle(scene.zero_point, 1, scene.inertial_frame.y)
    scene.lambdify_system(())
    scene.evaluate_system()
    # scene.plot()  # Forget to run plot.
    plt.show()
  2. Hover with your mouse over the figure.

This will throw the following error:

Traceback (most recent call last):
  File "...\site-packages\matplotlib\cbook.py", line 298, in process
    func(*args, **kwargs)
  File "...\site-packages\symmeplot\matplotlib\scene.py", line 182, in _hover
    plot_object = self._get_selected_object(event)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "...\site-packages\symmeplot\matplotlib\scene.py", line 164, in _get_selected_object
    if plot_object.contains(event):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "...\site-packages\symmeplot\matplotlib\plot_base.py", line 68, in contains
    return any(artist.contains(event)[0] for artist in self.artists)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "...\site-packages\symmeplot\matplotlib\plot_base.py", line 68, in <genexpr>
    return any(artist.contains(event)[0] for artist in self.artists)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "...\site-packages\matplotlib\patches.py", line 160, in contains
    codes = self.get_path().codes
            ^^^^^^^^^^^^^^^
  File "...\site-packages\mpl_toolkits\mplot3d\art3d.py", line 454, in get_path
    self.axes.M = self.axes.get_proj()
                  ^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get_proj'

Expected behavior
Two changes should ideally be made:

  1. Scene3D should postpone modification of the axes such that no references will be made to the artists. This can be done by attaching the motion notify event in plot instead of in __init__.
  2. Additionally, plot should be modified such that it can only be run once. When ran a second time it should raise an error explaining the the scene has already been plotted and update should be used to update the objects in the figure.

Additional context
This issue was found in bicycle-kickplate-model #34.

@tjstienstra tjstienstra added the bug Something isn't working label Oct 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant