如何使用matplotlib将3d数据单元转换为显示单位?

时间:2012-04-30 19:03:43

标签: 3d matplotlib

这可能有点疯狂,但我正在尝试使用matplotlib v1.1.0创建一个三维散点图的可点击图像映射。我已经阅读了如何为2d情节(c.f。this blog)做到这一点,但是3d让我感到困惑。基本问题是我不知道如何获得3d轴的显示坐标。

在第二种情况下,为了使点击点正确位于散点图上,您需要将每个散点点从数据单位转换为显示单位。使用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显示坐标,但在上网几个小时后我找不到它。有谁知道如何正确地做到这一点?

1 个答案:

答案 0 :(得分: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()