[英]Annotate 3D scatter plot on pick event
当用户单击一个点时,我想在 3D 分散 plot 上显示注释。
在我单击一个点后移动 plot后,我的代码会显示注释。
from mpl_toolkits.mplot3d import proj3d
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x = [1, 2, 3]
y = [1, 2, 3]
z = [1, 2, 3]
scatter = ax.scatter(x,y,z,picker=True)
def annotate_onclick(event):
point_index = int(event.ind)
print(point_index)
proj = ax.get_proj()
x_p, y_p, _ = proj3d.proj_transform(x[point_index], y[point_index], z[point_index], proj)
plt.annotate(str(point_index), xy=(x_p, y_p))
fig.canvas.mpl_connect('pick_event', annotate_onclick)
plt.show()
如何在用户单击某个点时立即显示注释,而无需移动 plot?
在回调 function 的末尾添加fig.canvas.draw_idle()
以强制重新绘制新注释。
嗯,当使用 Matplotlib 3.4 时,索引会根据屏幕上 3dgraph 的方向翻转,它会抛出这一切。 运行代码将图形旋转 180 度并单击点。 太可怕了。
#!/usr/bin/env python3
from mpl_toolkits.mplot3d import proj3d
import matplotlib.pyplot as plt
import matplotlib
print('matplotlib: {}'.format(matplotlib.__version__))
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x = [0, 2, 0,0]
y = [0, 2, 0,2]
z = [0, 2, 2,0]
scatter = ax.scatter(x,y,z,picker=True)
def chaos_onclick(event):
point_index = int(event.ind)
print(point_index)
#proj = ax.get_proj()
#x_p, y_p, _ = proj3d.proj_transform(x[point_index], y[point_index], z[point_index], proj)
#plt.annotate(str(point_index), xy=(x_p, y_p))
print("X=",x[point_index], " Y=",y[point_index], " Z=",z[point_index], " PointIdx=", point_index)
fig.canvas.mpl_connect('pick_event', chaos_onclick)
plt.show()
好的,这是使用从Matplotlib 收集的信息的解决方法: Annotating a 3D scatter plot 。
#!/usr/bin/env python3
from mpl_toolkits.mplot3d import proj3d
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
print('matplotlib: {}'.format(matplotlib.__version__))
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x = [0, 2, 0,0]
y = [0, 2, 0,2]
z = [0, 2, 2,0]
scatter = ax.scatter(x,y,z,picker=True)
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
def onMouseMotion(event):
print(event)
def chaos_onclick(event):
print(dir(event.mouseevent))
xx=event.mouseevent.x
yy=event.mouseevent.y
#magic from https://stackoverflow.com/questions/10374930/matplotlib-annotating-a-3d-scatter-plot
x2, y2, z2=proj3d.proj_transform(x[0], y[0], z[0], plt.gca().get_proj())
x3, y3 = ax.transData.transform((x2, y2))
#the distance
d=np.sqrt ((x3 - xx)**2 + (y3 - yy)**2)
print ("distance=",d)
#find the closest by searching for min distance.
#All glory to https://stackoverflow.com/questions/10374930/matplotlib-annotating-a-3d-scatter-plot
imin=0
dmin=10000000
for i in range(len(x)):
#magic from https://stackoverflow.com/questions/10374930/matplotlib-annotating-a-3d-scatter-plot
x2, y2, z2=proj3d.proj_transform(x[i], y[i], z[i], plt.gca().get_proj())
x3, y3 = ax.transData.transform((x2, y2))
#the distance magic from https://stackoverflow.com/questions/10374930/matplotlib-annotating-a-3d-scatter-plot
d=np.sqrt ((x3 - xx)**2 + (y3 - yy)**2)
#We find the distance and also the index for the closest datapoint
if d< dmin:
dmin=d
imin=i
#print ("i=",i," d=",d, " imin=",imin, " dmin=",dmin)
# gives the incorrect data point index
point_index = int(event.ind)
print("Xfixed=",x[imin], " Yfixed=",y[imin], " Zfixed=",z[imin], " PointIdxFixed=", imin)
print("Xbroke=",x[point_index], " Ybroke=",y[point_index], " Zbroke=",z[point_index], " PointIdx=", point_index)
fig.canvas.mpl_connect('pick_event', chaos_onclick)
#fig.canvas.mpl_connect('motion_notify_event', onMouseMotion) # on mouse motion
plt.show()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.