0

我使用这个示例代码作为我的起始代码

此代码生成条形图。当用户点击条形图上的实际条时,会触发一个事件并显示各个条的边界框坐标。这发生在 on_pick 函数中。

我修改了代码,所以我有一个Axes3D 线图,而不是条形图。我在这个 XYZ 坐标系上绘制了几条单独的线。我需要的是识别点击了哪一行。边界框似乎不适用于 3D 绘图,因为它对条形图起作用。

我查看了 pick_event 文档,但未能找到解决方案。我可以简单地检测单击位置的 x,y 坐标,但由于绘图可以以任意角度旋转,因此似乎很难检测实际单击了哪条线,特别是因为它们可能会根据视点重叠。

感谢您的时间和帮助!

4

1 回答 1

2

如果你只需要知道点击了哪条曲线,那并不是很困难。您需要创建一个 line_picker() 来检查鼠标位置是否足够接近曲线。

line_picker() 需要计算点和线段之间的距离,这有点困难,我通过使用曲线的线性插值来解决这个问题。

这是代码,我将曲线插值2000个点,如果鼠标到曲线的位置小于5像素,则选择曲线。

import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

def line_picker(line, me):
    if me.xdata is None: return False, dict()    
    x, y = me.x, me.y
    xdata, ydata = line.axes.transData.transform(np.array(line.get_data()).T).T
    index = np.arange(len(xdata))
    index2 = np.linspace(0, index[-1], 2000)
    xdata2 = np.interp(index2, index, xdata)
    ydata2 = np.interp(index2, index, ydata)
    d = np.sqrt((xdata2-x)**2. + (ydata2-y)**2.)
    if np.min(d) < 5:
        return True, {}
    else:
        return False, {}

mpl.rcParams['legend.fontsize'] = 10

fig = plt.figure()
ax = fig.gca(projection='3d')
theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
z = np.linspace(-2, 2, 100)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
line1 = ax.plot(x, y, z, label='parametric curve', picker=line_picker)[0]

t = np.linspace(-1, 1, 100) 
x = 4*np.sin(10*t)
y = 4*np.cos(10*t)
z = t**2*5-3

line2 = ax.plot(x, y, z, label="second", picker=line_picker)[0]

ax.legend()

def onpick(event):
    print [line1, line2].index(event.artist)

fig.canvas.mpl_connect('pick_event', onpick)

plt.show()
于 2012-05-28T01:33:35.997 回答