Skip to content

[Bug]: invalid value encountered with 'ortho' projection mode #22624

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
patquem opened this issue Mar 8, 2022 · 10 comments · Fixed by #22628
Closed

[Bug]: invalid value encountered with 'ortho' projection mode #22624

patquem opened this issue Mar 8, 2022 · 10 comments · Fixed by #22628
Labels
status: has patch patch suggested, PR still needed topic: mplot3d
Milestone

Comments

@patquem
Copy link
Contributor

patquem commented Mar 8, 2022

Bug summary

Hello,

Passing the mouse on the figure when plot has been generated with 'ortho' projection 3d mode and specific azimuthal and elevation angles returns the following message :

C:....\lib\site-packages\mpl_toolkits\mplot3d\proj3d.py:25: RuntimeWarning: invalid value encountered in double_scalars
u = (x01x21 + y01y21) / (x21¨¨2 + y21¨¨2)

Could you please investigate this ?
thanks,
Patrick

Code for reproduction

import matplotlib.pyplot as plt

fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.scatter(0, 0)
ax.set_proj_type('ortho')
ax.view_init(azim=-90, elev=90)
plt.show()

Actual outcome

C:....\lib\site-packages\mpl_toolkits\mplot3d\proj3d.py:25: RuntimeWarning: invalid value encountered in double_scalars
u = (x01x21 + y01y21) / (x212 + y212)

Expected outcome

No RuntimeWarning message

Additional information

No response

Operating system

Windows

Matplotlib Version

3.4.2

Matplotlib Backend

No response

Python version

3.7.7

Jupyter version

No response

Installation

pip

@oscargus oscargus added topic: mplot3d status: has patch patch suggested, PR still needed labels Mar 8, 2022
@oscargus
Copy link
Member

oscargus commented Mar 8, 2022

The warning occurs the first time x21 and y21 both are 0 (so it is a divide by zero error).

A simple way fix it is to change the code to something like:

    if x21 != 0 or y21 != 0:
        u = (x01*x21 + y01*y21) / (x21**2 + y21**2)
        u = np.clip(u, 0, 1)
    else:
        u = 0   # Actually doesn't matter since it will be multiplied by zero anyway...

although the preferred syntax may differ.

@patquem
Copy link
Contributor Author

patquem commented Mar 8, 2022

thanks @oscargus fror your reply
there is this other possibility :

with np.errstate(divide='ignore'):
    u = (x01*x21 + y01*y21) / (x21**2 + y21**2)

Whatever, I think one of this bugfix should be push in the next release.
Could you please be in charge of that ?
Thanks,
Patrick

@oscargus
Copy link
Member

oscargus commented Mar 8, 2022 via email

@oscargus
Copy link
Member

oscargus commented Mar 9, 2022

Seems like one should use invalid='ignore' as although there is a division by zero, the actual warning is "Invalid..." (probably because it is 0/0). For now, I went with my approach (as I didn't figure out the answer above until after pushing it...), but we'll see what the review leads to.

@anntzer
Copy link
Contributor

anntzer commented Mar 10, 2022

The warning is triggered when trying to get xyz coordinates for the mouse cursor and one of the axes is exactly orthogonal to the screen, but I wonder whether printing xyz coordinates in the toolbar even makes sense at all? Basically, we pick an arbitrary screen-z-depth for the cursor (based on the distance to the edges -- which is where the warning comes from) and print the corresponding xyz value, but if one e.g. carefully looks at the displayed xyz values while slowly moving the mouse across a (default, non-ortho) 3d axes, one will see that the value suddenly jumps when the mouse goes from "closer to one axis" to "closer to another axis".
In other words, I would suggest to just stop displaying mouse cursor xyz values here. (Also compare with e.g. mayavi, which doesn't display them either.)

@WeatherGod
Copy link
Member

WeatherGod commented Mar 10, 2022 via email

@anntzer
Copy link
Contributor

anntzer commented Mar 10, 2022

I am not convinced the values make sense at all. For example, these are the xyz values printed when dragging the mouse across window (default 3d view) horizontally, along the middle y position:

from pylab import *
from matplotlib.backend_bases import LocationEvent
rcdefaults(); rcParams["axes.unicode_minus"] = False  # use ascii minus
fig = figure()
ax = fig.add_subplot(projection="3d")
fig.canvas.draw()
xyzs = []
screen_ry = .5
# drag mouse across window horizontally, along the middle y position
for screen_rx in np.linspace(0, 1, 1001):
    screen_xy = fig.transFigure.transform((screen_rx, screen_ry))
    pseudo_xy = ax.transData.inverted().transform(screen_xy)
    ev = LocationEvent("", fig.canvas, *screen_xy)
    ev.xdata, ev.ydata = pseudo_xy
    if any([axis.pane.contains(ev)[0] for axis in ax._axis_map.values()]):
        s = ax.format_coord(*pseudo_xy)  # formatted string
        xyzs.append([float(part.split("=")[1]) for part in s.split(",")])  # displayed xyz
    else:  # out of Axes
        xyzs.append((np.nan, np.nan, np.nan))
xyzs = array(xyzs)
close(fig)
plot(xyzs[:, 0], label="x")
plot(xyzs[:, 1], label="y")
plot(xyzs[:, 2], label="z")
legend()
show()

xyz

The jumping is... not nice.

@anntzer
Copy link
Contributor

anntzer commented Mar 16, 2022

when this feature has broken for other reasons, users have noticed and complained

Actually, I have quickly skimmed through the issue list and didn't find anything related, but perhaps you have refs e.g. on the mailing list?

@WeatherGod
Copy link
Member

Ok, so I am also having difficulty finding what I was thinking of, but, here are some issues where people expressed interest in having access to 3D coordinate information:

#16156
#11309
https://discourse.matplotlib.org/t/no-zdata-in-motion-notify-event-when-using-a-3d-plot/16201

This isn't a comprehensive listing of such interest, and it shows that users find the information that is displayed by format_coords() to be useful enough to want to know more about how to get it programmatically. While I haven't had time to look closely at what you showed above, that isn't an argument to get rid of it; it is an argument to make it better behaved.

@anntzer
Copy link
Contributor

anntzer commented Mar 20, 2022

I don't disagree with making it better behaved. However, the value currently displayed is simply worse than useless, it is misleading (it does not correspond to the dot they are pointing to).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: has patch patch suggested, PR still needed topic: mplot3d
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants