[英]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.