2012-04-30 5 views
2

これはちょっと狂っているかもしれませんが、私は、matplotlib v1.1.0を使って3D散布図のクリック可能なイメージマップを作成しようとしています。私は2dプロット(c.f. this blog)のためにそれを行う方法を読んだことがありますが、3dは私を神秘的にしました。基本的な問題は、3D軸の表示座標を取得する方法がわかりません。3次元データユニットをmatplotlibで表示する方法は?

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)) 

最後の行は、しかし、私に「無効な頂点配列」エラーが発生します。 2つの点のタプル(たとえば1,1)を渡す場合にのみ機能しますが、3次元プロットには意味がありません。 3D投影を2D表示座標に変換する方法があるはずですが、数時間インターネットを壊してしまえば見つけられません。誰もこれを正しく行う方法を知っていますか?

答えて

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() 
関連する問題