问题描述
我在 3D 散点图上显示了一些点,我想突出显示被点击的点。但是 ind["ind"][0] 根据图表上 x 轴(顶部或底部)或 y 轴(左侧或右侧)的位置给出了所选点的错误索引。因此,突出显示的不是我点击的那个。
问候,
马特
import matplotlib.pyplot as plt
import numpy as np
Lx = 0.8
Ly = 0.5
n = 10
Nx = 8
Ny = 5
x = np.linspace(0,Lx,Nx)
y = np.linspace(0,Ly,Ny)
X,Y = np.meshgrid(x,y)
#visualisaiton 3D
fig = plt.figure('Visualisation 3D')
ax2 = plt.subplot(1,1,projection='3d')
ac_x,ac_y = 1,1
sc = ax2.scatter(X.ravel(),Y.ravel(),np.zeros(Nx * Ny),picker=True)
ac = ax2.scatter(x[ac_x],y[ac_y],'r',s=50)
def click(event,ind):
i = ind["ind"][0]
xx,yy,zz = sc._offsets3d
def find_nearest(array,value):
array = np.asarray(array)
idx = (np.abs(array - value)).argmin()
return idx
ac_x = np.where(x == xx[i])[0]
ac_y = np.where(y == yy[i])[0]
print('xx[i],yy[i]: (%.2f,%.2f)' % (xx[i],yy[i]))
print('Click at: (%.2f,yy[i]))
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))
ac_act = ax2.scatter(x[ac_x],s=50)
print('index (%d,%d) position: (%.2f,%.2f)' % (ac_x,ac_y,x[ac_x],y[ac_y]))
def on_click(event):
if event.inaxes == ax2:
cont2,ind2 = sc.contains(event)
if cont2:
click(event,ind2)
fig.canvas.draw_idle()
fig.canvas.mpl_connect('button_press_event',on_click)
plt.show()
工作示例:
不工作:
解决方法
我在从 Path3DCollection 获取正确索引时也遇到了一些麻烦。经过一番挖掘,我发现数据数组是根据 z 坐标重新排序的。要获取原始索引,您需要访问成员_z_markers_idx,不幸的是该成员受到保护。
在文件中:
mpl_toolkits\mplot3d\art3d.py
我向 Path3DCollection 类添加了以下 getter:
def get_z_markers_idx(self):
return self._z_markers_idx
然后您就可以通过以下方式获取正确的索引:
def click(event,ind):
i = sc.get_z_markers_idx()[ind["ind"][0]]