Matplotlib: ax.format_coord() in 3D trisurf plot -

2019-08-14 06:39发布

I was trying to redo this already answered question Matplotlib - plot_surface : get the x,y,z values written in the bottom right corner, but wasn't capable of getting the same result, as stated there. So, I have a code like:

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from plyfile import PlyData, PlyElement

#Handle the "onclick" event
def onclick(event):
    print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
          ('double' if event.dblclick else 'single', event.button,
           event.x, event.y, event.xdata, event.ydata))
    print(gety(event.xdata, event.ydata))

#copied from https://stackoverflow.com/questions/6748184/matplotlib-plot-surface-get-the-x-y-z-values-written-in-the-bottom-right-cor?rq=1
def gety(x,y):
    s = ax.format_coord(x,y)
    print(s) #here it prints "azimuth=-60 deg, elevation=30deg"
    out = ""
    for i in range(s.find('y')+2,s.find('z')-2):
        out = out+s[i]
    return float(out)

#Read a PLY file and prepare it for display
plydata = PlyData.read("some.ply")
mesh = plydata.elements[0]
triangles_as_tuples = [(x[0], x[1], x[2]) for x in plydata['face'].data['vertex_indices']]
polymesh = np.array(triangles_as_tuples)

#Display the loaded triangular mesh in 3D plot
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_trisurf(mesh.data['x'], mesh.data['y'], mesh.data['z'], triangles=polymesh, linewidth=0.2, antialiased=False)
fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()

With this, the triangular surface is properly displayed (although slowly). I can see the (x,y,z) coordinates of the surface in the bottom right corner, while I hover over the plot. But when I try to get these coordinates with the click of mouse (through the connected event handler), the ax.format_coord(x,y) fction returns not a string of cartesian coordinates, but a string of "azimuth=-60 deg, elevation=30deg", no matter where in the plot I click, until the surface is rotated. Then it returns another values. From this I suppose these are spherical coordinates of the current view, not the clicked point, from some reason...

Can someone find out, what am I doing wrong? How do I can get the cartesian coordinates on the surface?

FYI: This all is related to my previous question Python: Graphic input in 3D, which was considered too broad and generic.

1条回答
Ridiculous、
2楼-- · 2019-08-14 07:16

The mousebutton being pressed is the trigger for ax.format_coord to return the angular coordinates on a 3D plot instead of the cartesian ones. So an option is would be to let the ax.format_coord think that no button is pressed, in which case it would return the usual cartesian x,y,z coordinates as desired.

A bit of a hacky way to achieve this, even though you clicked the mousebutton, would be to set the ax.button_pressed (which stores the current mousebutton) to something unreasonable while calling that function.

def gety(x,y):
    # store the current mousebutton
    b = ax.button_pressed
    # set current mousebutton to something unreasonable
    ax.button_pressed = -1
    # get the coordinate string out
    s = ax.format_coord(x,y)
    # set the mousebutton back to its previous state
    ax.button_pressed = b
    return s
查看更多
登录 后发表回答