簡體   English   中英

在選擇事件上注釋 3D scatter plot

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM