2

这可能有点疯狂,但我正在尝试使用 matplotlib v1.1.0 创建 3d 散点图的可点击图像映射。我已经阅读了如何为 2d 绘图(参见此博客),但 3d 让我感到困惑。基本问题是我不知道如何获取 3d 轴的显示坐标。

在 2d 情况下,为了让点击点正确位于散点上方,您需要将每个散点从数据单位转换为显示单位。使用ax.transData似乎相当简单。我希望这也适用于 3d 轴,但似乎不行。例如,这是我试图做的:

# create the plot
from mpl_toolkits.mplot3d import Axes3D
fig = pylab.figure()
ax = fig.add_subplot(111, projection = '3d')
x = y = z = [1, 2, 3]
sc = ax.scatter(x,y,z)
# now try to get the display coordinates of the first point
sc.axes.transData.transform((1,1,1))

然而,最后一行给了我一个“无效的顶点数组”错误。它仅在您将两个点的元组传递给它时才有效,例如 (1,1),但这对于 3d 绘图没有意义。一定有一种方法可以将 3d 投影转换为 2d 显示坐标,但是在互联网上捣毁了几个小时后我找不到它。有谁知道如何正确地做到这一点?

4

1 回答 1

3

您可以使用proj3d.proj_transform()将 3D 坐标投影到 2D。调用ax.get_proj()获取变换矩阵:

import pylab
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d import proj3d
fig = pylab.figure()
ax = fig.add_subplot(111, projection = '3d')
x = y = z = [1, 2, 3]
sc = ax.scatter(x,y,z)

#####################    
x2, y2, _ = proj3d.proj_transform(1, 1, 1, ax.get_proj())
print x2, y2   # project 3d data space to 2d data space
print ax.transData.transform((x2, y2))  # convert 2d space to screen space
#####################
def on_motion(e):
    # move your mouse to (1,1,1), and e.xdata, e.ydata will be the same as x2, y2
    print e.x, e.y, e.xdata, e.ydata  
fig.canvas.mpl_connect('motion_notify_event', on_motion)
pylab.show()
于 2012-05-01T05:32:04.263 回答